栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

[ C语言 ]循环语句---while---for---do while---详解及练习题巩固

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[ C语言 ]循环语句---while---for---do while---详解及练习题巩固

文章目录
  • 前言
  • 一,while 循环
  • 二,for   循环
  • 三,do  while 循环
  • 四,练习题巩固
  • 总结







前言

本篇内容主要记录 循环语句:

包括while循环,for循环,do...while循环详细讲解以及习题巩固练习

____________________________________________________________________________

                                                                     ****正文开始****

一、while 循环

在我们的日常生活中有很多实际的例子:

同一件事情我们需要完成很多次。 那我们怎么做呢? C语言中给我们引入了: while 语句,可以实现循环。
//while 语法结构
while(表达式)
 循环语句;

Q : 比如我们实现:在屏幕上打印1-10的数字。

int main() {

	int i = 0; // 初始化
	while (i <= 10) {// 判断

		printf("%d ", i);

		i++;       //调整部分
	}
	return 0;
}
这段代码中已经足够清晰的反应了程序的执行过程。 上面的代码已经帮我们了解了 while 语句的基本语法。 那我们再了解一下: (一)while语句中的break和continue 1>break在while循环中

Q : 我们看这段代码,它的执行结果是什么呢?

int main() {
	int  i = 1;
	while (i <= 10) {
		if (5 == i)
			break;
	

		printf("%d ", i);
		i++;
	}
	return 0;
}
我们看代码运行结果:

我们发现了break在while循环中的作用:

其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 所以:while中的break是用于永久终止循环的。

2>continue在while循环中

Q : 我们看这段代码,它的执行结果是什么呢?

int main() {
	int  i = 1;
	while (i <= 10) {
		if (5 == i)
			
		continue;// continue 会跳过后面的语句

		printf("%d ", i);
		i++;
	}
	return 0;
}

我们看运行结果:

 Q : 我们再看这段代码,它的执行结果是什么呢?

int main() {
	int  i = 1;
	while (i <= 10) {
		i++;

		if (5 == i)
		
		continue;// continue 会跳过后面的语句

		printf("%d ", i);
	
	}
	return 0;
}

我们看它的运行结果:

 我们能够发现:第一段代码运行到4之后,当i==5的时候发生了死循环。这是因为continue起了作用,我们就要提到continue 的作用了。

continue在while循环中的作用就是: continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行, 而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。 A : 因此第一段代码中当 i==5 的时候,走到continue时跳出了本次循环到了,但是这时候 i 还并没有i++,当下一次 i 进入循环的时候,i 的值还是5,再次continue,这就造成了死循环。 同理: Q : 为什么第二段代码没有造成死循环呢? A : 其实我们只要自己观察分析代码会发现,在 if 判断之前 i++ 了一次;这就会导致当 i==5时,continue跳出本次循环时,在下一次进入循环的时候 i 并不是仍然是5,而是6(因为i++了一次),所以 if 判断为假,不会continue跳出循环,而且会打印 数字,因此这就是为什么第二段代码没有造成死循环,并且打印的结果中没有数字5。  (二)getchar 详解

Q : 我们在观察这段代码,他是什么意思?

int main() {

	int ch = 0;
	while ((ch = getchar())!= EOF) {
		putchar(ch);
	}

	return 0;
}

这里的代码适当的修改是可以用来清理缓冲区的.

#include 
int main()
{
    char ch = '';
 while ((ch = getchar()) != EOF)
 {
     if (ch < ‘0’ || ch > ‘9’)
        continue;
     putchar(ch);
 }
 return 0; }

这个代码的作用是:只打印数字字符,跳过其他字符的

举例:  请观察这段代码?他会正常输出我们想要的结果吗?

int main() {
	char input[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", input); // abcdef
	
	getchar(); // 拿走 n


	printf("请输入密码(Y/N):>");
	
	int ch = getchar();
	if (ch == 'Y') {
		printf("确认成功n");
	}
	else {
		printf("确认失败n");

	}
	return 0;
}

查看运行结果:

 我们发现如果连续的输入一段数字,程序会正常按照我们的意思输出,但是如果我们更改输入的方法,他还会正常吗?

我们观看这样的输入方式:

 在这里我们输入的密码:123  456

我们在123和456之间加入一个空格,我们发现这就导致了我们直接略过了判断密码是否争取的那一步,并且输出了确认失败,这是为什么呢?

这是因为:

我们从键盘输入: 123 456

实际上是: 123 456n

读取字符串的时候,遇到空格就结束了,所以getchar只都读走了123

缓冲区内部还有:_ (空格)456n

所以一个getchar并不能解决问题,应该使用一种方法将缓冲区的所有字符带走,这时候就可以运用while循环,具体代码如下:

//清理缓冲区
	int tmp = 0;
	while ((tmp = getchar()) != 'n') {
		;  //空语句
	}

通过清理缓冲区这时候就可以达到我们想要的结果:

整体代码如下:

int main() {
	char input[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", input); // 123 456
	 
	//清理缓冲区
	int tmp = 0;
	while ((tmp = getchar()) != 'n') {
		;  //空语句
	}


	printf("请输入密码(Y/N):>");

	int ch = getchar();
	if (ch == 'Y') {
		printf("确认成功n");
	}
	else {
		printf("确认失败n");

	}
	return 0;
}

我们再看 演示结果:

 我们发现解决了问题

二,for   循环 一:语法
for(表达式1; 表达式2; 表达式3)
 循环语句;
表达式1 表达式1为初始化部分,用于初始化循环变量的。 表达式2 表达式2为条件判断部分,用于判断循环时候终止。 表达式3 表达式3为调整部分,用于循环条件的调整。

我们继续以实例的方式了解for循环语句:

实际的问题: Q :使用for循环 在屏幕上打印1-10的数字。
int main() {
	int i = 0;
    //for(i=1; i<=10; i++)
	for (i = 1; i <= 10; i++){

		printf("%d ", i);

	}
	return 0;
}

现在我们来对比一下while循环和for循环:

int i = 0;
//实现相同的功能,使用while
i = 1;//初始化部分
while (i <= 10)//判断部分
{
	printf("hehen");
	i = i + 1;//调整部分
}
//实现相同的功能,使用while
for (i = 1; i <= 10; i++) {
	printf("hehen");
}
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。 (一)break和continue在for循环中 我们发现在 for 循环中也可以出现 break 和 continue ,他们的意义和在 while 循环中是一样的。 但是还是有些差异: 1>break 在for循环中
//代码1
#include 
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
	}
	return 0;
}

我们观察运行结果:

我们观察到输出的结果为:1 2 3 4 

这是因为: 当 i == 5 进入 if 判断当中时,直接跳出 for 循环 

到达 return 0; 

因此打印出 : 1 2 3 4(和while 循环类似)

其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 2>continue 在for循环中
#include 
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}
我们观察运行结果:

我们观察到输出的结果是:1 2 3 4 6 7 8 9 10 跳过了数字5,但是它并不是和while循环一样发生了死循环,这是因为for在执行的时候会有执行顺序,当表达式2成立进入循环时遇到continue跳出本次循环时,会接着执行表达式3,也就是调整部分,i 会 i++,这时候 i 会自增成6,在下一次进入循环时,不进入 if 判断。 因此: 我们从结果上就会得到:打印出1 2 3 4  6 7 8 9 10 跳过了数字 5 的打印。 这就是continue在for循环中的作用 建议:    for (i = 0; i < 10; i++)  ----->建议写成前闭后开,10表示打印10次 提高可读性  1. for  的舒适化,判断,调整三个部分都可以省略
 2. 中间的判断部分如果省略,意味着判断恒为真,就构成了死循环
 3. 如果条件允许,不建议省略for循环的3个表达式 死循环举例:
	for (;;) {

		printf("hehen");// 死循环打印hehe
	}

我们再来看这段代码:

    int i = 0;
    int j = 0;
    for (i = 0; i < 3; i++){
        for (j = 0; j < 3; j++) {
            printf("hehen");
        }
    }

我们看运行结果:

我们发现这个程序打印了 9 行 hehe,这是因为当 i ==0 进入程序的时候 j 从0开始循环,当 j == 0 时, 打印一遍 hehe;当 j == 1 时, 打印第二遍 hehe ,d ;当 j == 2 ,打印第三遍 hehe;当 j ==3 不小于3的时候跳出 j 的循环 这时候 i++,此时 i == 1,同理,j 又从0开始打印 3遍hehe;i 再 i++;j 又打印3遍hehe,当 i==3 时 ,i < 3 不成立时,退出循环 ,这时候统计发现一共打印了9遍呵呵。

但是,如果我们省略表达式一(初始化),打印的结果会完全不同。

int main() {
	int i = 0;
	int j = 0;
	for (; i < 3; i++) {
		//  j = 3 没再初始化了
		for (; j < 3; j++) {
			printf("hehen"); // 打印3个hehe
		}
	}
	return 0;
}

我们观察运行结果:

 这是因为当 i++ 增到 i==1 进入j 的循环时,j 并没有初始化,还是i=1时候的i++是3,不会再进入j 的循环,因此只会打印  i ==1 第 一 次的3 个hehe。 总结:如果条件允许,不建议省略for循环的3个表达式 我们再来看这一道题 : 
//int main() {
//	int i = 0;
//	int k = 0; 
//	         // k = 0  赋值0  结果是0  表示假 不进入循环
//	for (i = 0, k = 0; k = 0; k++) {
//		k++;
//	}
//	return 0;
//}

Q:问这段代码循环几次?

A : 通过代码我们发现 for循环中的表达式2 是k = 0,‘=’是赋值符号,因此是将数字0赋值给k,我们知道在C语言中0表示假,因此表达式2 判断为假,根本不会进入for循环,因此这段代码循环0次。

三,do  while 循环 do 语句的语法:
do
 循环语句;
while(表达式);
do语句的特点 :  循环至少执行一次,使用的场景有限,所以不是经常使用
#include 
int main()
{
	int i = 1;
	do
	{
		printf("%dn", i);
        i++;
	} while (i < 10);
	return 0;
}

这段代码是用while循环打印1-10。

(一)do while循环中的break和continue 1> break 在 do  while  循环中
int main() {
	int i = 1;
	do {
		if (i == 5)
			break;//打印 1 2 3 4
	
		printf("%d ", i);
		i++;
	} while (i <= 10);

	return 0;
}

道理同break在while和for循环中一样。

2> continue 在 do  while  循环中
int main() {
	int i = 1;
	do {
		if (i == 5)
			
		   continue;// 1 2 3 4死循环
		printf("%d ", i);
		i++;
	} while (i <= 10);

	return 0;
}

运行结果:

 原因和while循环中的道里一致,因为continue是跳出本次循环,不会执行后面的i++,所以如果当i==5时就会一直死循环。

这时候我们如果将i++放到continue之前结果为:

int main() {
	int i = 1;
	do {
		i++;
		if (i == 5)
			
		   continue;// 1 2 3 4死循环
		printf("%d ", i);
	
	} while (i <= 10);

	return 0;
}

 我们发现和while循环中的将i++的第二种可能性一直,道理相同。

四,练习题巩固 1.计算n的阶乘
int main() {

	int n = 0;
	scanf("%d", &n);// 5
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++) {
		ret *= i;
	}
	printf("%dn",ret);
	return 0;
}
 2.计算 1!+2!+3!+4!+.....n!
int main() {
	int n = 0;//共n个数字
	scanf("%d", &n);
	int i = 0;// j  内部的第 i 个数字
	int j = 0;// n  内部的第 j 个数字
	int sum = 0;

	for (j = 1; j <= n; j++) {// 
		int ret = 1;
		for (i = 1; i <= j; i++) {
			ret *= i;
		}
		sum += ret;
	}
	printf("%dn", sum);
	return 0;
}

当然这道题我们还有优化算法:

int main() {
	int n = 0;
	int i = 0;
	int ret = 1;
	int sum = 0;
	for (n = 1; n <= 10; n++) {
		ret = ret * n;
		sum += ret;
	}
	printf("%dn", sum);
	return 0;
}
3.在一个有序数组中查找具体的某个数字n(二分查找)

这个是普通求法:

int main() {
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int i = 0;
	for (i = 0; i < 10; i++) {
		if (arr[i] == k) {
			printf("找到了,下标是%dn", i);
			break;
		}
		else if (i == 10) {
			printf("找不到n");
		}
	}
	return 0;
}

我们发现,如果说这个数组中定义了100甚至更多的数字时,这样的算法就会耗时耗力,因为有一种更简便的算法:

二分法 -- 折半查找

int main() {
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	 //         40       /    4  = 10
	int k = 7;
	int left = 0;
	int right = sz - 1;


	while (left <= right) {
		int mid = (left + right) / 2;
		if (arr[mid] < k) {
			left = mid + 1;
		}
		else if (arr[mid] > k) {
			right = mid - 1;
		}
		else {
			printf("找到了,下标是%d n", mid);
			break;
		}
	}
	if (left > right) {
		printf("找不到n");
	}
	return 0;
}
  4:反向打印一个数字
int main() {
	int n = 0;
	scanf("%d", &n);
	while (n!=0) {
		printf("%d", n % 10);
		n = n / 10;
	}
	return 0;
}

                                                                   ****正文结束****

———————————————————————————————————————————







总结

本篇文章的内容就记录完毕,由于本人技术水平有限,若各位读者发现错误,欢迎及时纠正。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352377.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号