IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [ C语言 ]循环语句---while---for---do while---goto语句详解及练习题巩固 -> 正文阅读

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

文章目录

  • 前言
  • 一,while 循环
  • 二,for? ?循环
  • 三,do? while 循环
  • 四,goto语句
  • 五,练习题巩固
  • 总结



前言

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

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

____________________________________________________________________________

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

一、while 循环

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

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

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

int main() {

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

		printf("%d ", i);

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

(一)while语句中的breakcontinue

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)
			/*break;*/
		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 <stdio.h>
int main()
{
 ? ?char ch = '\0';
 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 456\n

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

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

所以一个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("hehe\n");
	i = i + 1;//调整部分
}
//实现相同的功能,使用while
for (i = 1; i <= 10; i++) {
	printf("hehe\n");
}
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。

(一)breakcontinuefor循环中

我们发现在 for 循环中也可以出现 break continue ,他们的意义和在 while 循环中是一样的。
但是还是有些差异:

1>break 在for循环中

//代码1
#include <stdio.h>
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 <stdio.h>
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("hehe\n");// 死循环打印hehe
	}

我们再来看这段代码:

?? ?int i = 0;
?? ?int j = 0;
?? ?for (i = 0; i < 3; i++){
?? ??? ?for (j = 0; j < 3; j++) {
?? ??? ??? ?printf("hehe\n");
?? ??? ?}
?? ?}

我们看运行结果:

我们发现这个程序打印了 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("hehe\n"); // 打印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 <stdio.h>
int main()
{
	int i = 1;
	do
	{
		printf("%d\n", i);
        i++;
	} while (i < 10);
	return 0;
}

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

(一)do while循环中的breakcontinue

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++的第二种可能性一直,道理相同。

四,goto语句

C 语言中提供了可以随意滥用的 goto 语句和标记跳转的标号。
从理论上 goto 语句是没有必要的,实践中没有 goto 语句也可以很容易的写出代码。
但是某些场合下 goto 语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如:一次跳出两层或多层循环。
多层循环这种情况使用 break 是达不到目的的。它只能从最内层循环退出到上一层的循环。
goto 语言真正适合的场景如下:
// 多层循环这种情况使用break是达不到目的的,他只能从最内层循环退出上一层的循环
// 这时候 goto语句适合这种场景
for () {
	for () {
		for () {
			if (disaster) {
				goto error;
			}
		}
	}
}
...
error:
if(disaster)
// 处理错误情况

goto again 用法(标签一致就行,但标签必须在同一个函数内)

int main() {

again:
	printf("hehe\n");
	printf("haha\n");
	goto again; // 标签一致就行,标签必须在同一个函数内

	return 0;
}

结果演示:?

会死循环打印hehe和haha.

小游戏,小整蛊:

//例如: 写一个关机程序
//只要程序启动了,就倒计时60秒关机,如果60秒之内,输入:我是猪,就取消关机,如果不输入,时间到就关机
  
 shutdown   windows提供的关机命令
 shutdown -s -t 60秒之后关机
 shutdown -a 取消关机
int main() {

	char input[20] = { 0 };
	system("shutdown -s -t 60");

again:
	printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
	scanf("%s", input);  //input本来就是地址 不用取地址
	//判断
	if (strcmp(input,"我是猪") == 0) {
		// 取消关机
		system("shutdown -a");
	}
	else {
		goto again;
	}

	return 0;
 }

五,练习题巩固

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("%d\n",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("%d\n", 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("%d\n", 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("找到了,下标是%d\n", 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;
}

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

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








总结

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-01 11:32:29  更:2021-11-01 11:32:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:29:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码