C语言—分支和循环语句2

本文详细介绍了C语言中的循环结构,包括while、for和do-while循环的语法、实践应用以及break和continue语句的使用。同时讨论了循环嵌套和特殊语句goto。通过实例展示了如何使用这些循环结构解决实际问题,如打印数字序列和判断素数。
摘要由CSDN通过智能技术生成


前言

上一篇博客我为大家介绍了分支语句中的if语句和switch语句的使用,这篇博客我将继续给大家分享循环结构。


二、循环语句

1. while循环

1.1 while

对比while 和 if 语句的语法,它们非常类似,语法形式如下:

if(表达式)
	语句;
while(表达式)
	语句;

相同的是首先进行判断表达式,表达式成立(为真),则语句执行;表达式不成立(为假),则语句不执行。区别是 while 若表达式不成立,语句将不执行,while 循环将直接结束,如果表达式成立,语句执行,执行完毕后会再次返回到“表达式”处判断,若为真,则语句执行,形成循环,直至表达式为假,while循环才会结束。

用流程图表示:
在这里插入图片描述

1.2 while循环的实践

学会了 while 的语法后,让我们尝试着使用while循环解决下面的问题:

在屏幕上打印1~100的值

#include <stdio.h>
int main()
{
	int i = 1;
	while(i <= 100)//条件
	{
		printf("%d ",i);//执行打印
		i++;//对条件内变量进行调整
	}
}

执行得到结果:
在这里插入图片描述
对于上面的代码大家或许有些许疑问:

  1. while 中的条件表达式怎么想出来的?
  2. 为什么在循环语句内要i++?

    首先,我们知道,while 的循环语句的是否执行由圆括号()内的条件表达式所决定,那么我们就要结合我们所面对的问题去设计这个条件表达式,要打印1~100的数,那我们必须要产生1 ~ 100的数字,所以我们创建一个临时变量 i 并赋值为1,只要我们每次打印完之后它能够在原基础上+1,那么我们就能得到这些数字,但我们也要控制它的范围,不能让它打印.加1.打印.加1就这样一直死循环下去,所以我们给定i<=100作为循环的条件表达式,当i>100时,循环结束。那怎么做到 i 每次+1呢?只要在循环语句内加上 i++ 就行了。

1.3 设计 while 条件表达式实现多组数据输入

通过上面的学习,我们感受到了圆括号内条件表达式的重要性。现在我将给大家介绍一种在牛客网刷题中经常出现的实现“多组输入”的方法。

BC41 你是天才吗?
描述:
据说智商140以上者称为天才,KiKi想知道他自己是不是天才,请帮他编程判断。输入一个整数表示一个人的智商,如果大于等于140,则表明他是一个天才,输出“Genius”。
输入描述:
多组输入 ,每行输入包括一个整数表示的智商。
输出描述:
针对每行输入,输出“Genius”。
示例1
输入:160
输出:Genius

这是一道非常简单的题目,让我们解答一下

#include <stdio.h>

int main() 
{
    int a = 0;
    scanf("%d",&a);
    if(a>=140)
        printf("Genius");
    return 0;
}

但仅仅是这样就结束了吗,细心的同学会发现在输入描述中给出了“多组输入”的要求,意思是程序运行后不止输入一组数据去判断一次智商,而是想实现判断完一次后程序紧接着再判断,这就使用到了循环语句。既然如此,我们现在已经写出了循环内的执行语句,就差条件判断语句了,这又该怎么设计呢?
这里我给大家一种写法:

while(sacnf("%d",&a)!=EOF)
{
	执行语句;
}

这里用到了 scanf() 函数的返回值,函数的具体知识我会在以后的博客中讲到,这里让我们简单学习 scanf() 函数的返回值。

scanf()函数的返回值是 “所输入的数据与格式字符串中匹配次数.”
简单来说就是,它返回已成功赋值的数据项数;出错时则返回EOF.
(注:EOF(End Of File)是一个预定义的常量,等于-1.)

让我们写一段程序来简单测试一下 scanf() 的返回值:

#include <stdio.h>
int main()
{
    int a = 0,b = 0; 
    int input = 0;//用于获取scanf函数的返回值
    input = scanf("%d %d",&a,&b);
    printf("input = %d",input);
    return 0;
}

若输入:1 2 ↙
输出:input = 2
说明:成功输入了两个整数.
在这里插入图片描述
若输入:1 a↙
输出:input = 1
说明:仅仅匹配了变量a,而整型变量b的格式字符串%d无法匹配字符‘a’,所以这里只有变量a被赋值成功,已成功赋值的数据项数为1,则返回值为1.

在这里插入图片描述
若输入:a b↙
输出:input = 0
说明:均未成功读入,已成功赋值的数据项数为0,则返回值为0

在这里插入图片描述
若输入:^Z ↙ ^Z↙ ^Z↙
会得到:input = -1
说明:输入出错,返回值为-1.
(注:ctrl+z输入代表输入文件结束符)

在这里插入图片描述

学会了scanf()函数的返回值的用法,大家或许已经知道怎样改写代码来实现上面拿道题的多组输入了。

#include <stdio.h>
int main()
{
    int a = 0;
    while(scanf("%d", &a) != EOF)
    {
        if(a>=140)
            printf("Genius");
    }
    return 0;
}

1.4 练习使用 while 循环

输⼊⼀个正的整数,逆序打印这个整数的每⼀位,要求多组输入
例如:
输⼊:1234,输出:4 3 2 1
输⼊:521,输出:1 2 5

题目解析

  1. 要想得到n的最低位,可以使用n%10的运算,得到的余数就是最低位,如:1234%10得到4
  2. 要想去掉n的最低位,找出倒数第⼆位,则使用 n=n/10 操作就可以去掉最低位的,如:
    n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第二位3。
  3. 循环1和2两个步骤,在n变成0之前,就能到所有的位。
  4. 多组输入只需将执行语句套入前面学过的方法中。

参考代码

#include <stdio.h>
int main()
{
	int n = 0;
	while(scanf("%d", &n)!=EOF)
	{
		while(n)
		{
			printf("%d ", n%10);
			n /= 10;
		}
		printf("\n");
	}
	return 0;
}

2. for 循环

2.1 for循环的语法形式

for 循环语法形式如下:

for(表达式1;表达式2;表达式3)
	语句;

表达式1 用于循环变量的初始化
表达式2 用于循环结束条件的判断
表达式3 用于循环变量的调整

首先执行 表达式1 初始化循环变量,接下来就是执行 表达式2 的判断部分,表达式2的结果如果==0,则循环结束; 表达式2 的结果如果!=0则执行循环语句,循环语句执行完后,再去执行 表达式3 ,调整循环变量,然后再去 表达式2 的地方执行判断, 表达式2 的结果是否为0,决定循环是否继续。
整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2、循环语句、表达式3在循环。

2.2 for 循环的实践

学习了 for 循环的语法以后,让我们尝试使用 for 循环解决以下问题:

在屏幕上打印1~100的数字

#include <stdio.h>
int main()
{
	for(int i = 1;i<=100;i++)
	{
		printf("%d",i);
	}
	return 0;
}

运行结果:
在这里插入图片描述

2.3 for 循环与 while 循环的对比

将 for 循环换成我们刚学过的 while 循环之后就是这样的:

表达式1;
while(表达式2)
{	
	语句;
	表达式3;
	//(语句)语句和表达式3位置可以交换甚至可以将表达式3插入语句中
}

在这里插入图片描述
for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分非常集中,便于代码的维护,而如果代码较多程序较复杂的时候 while 循环的三个部分就比较分散,所以从形式上 for 循环要更优一些。

2.4 练习使用for 循环

计算10的阶乘

参考代码:

#include <stdio.h>
int main()
{
	int ret = 1;
	for(int i = 1;i <= 10;i++)
	{
		ret*=i;
	}
	printf("%d",ret);
	return 0;
}

思考如何实现多组输入,计算n的阶乘?

3. do-while 循环

3.1 do-while 循环的语法形式

do
	语句;
while(表达式);

while 和 for 两种循环都是先进行判断,条件满足才会进入循环执行语句,若条件不满足则跳出循环。而do-while 循环则是先直接进入循环体执行一次循环语句,然后再执行 while 后的条件判断表达式,表达式为真则再次进入循环,表达式为假则结束循环。
注意: while()后一定要记得加上分号;。

3.2 do-while 循环的执行流程

在这里插入图片描述
由以上流程图我们知道,do-while 循环中循环体至少执行一次,这也是do-while循环的特点。

3.3 练习使用 do-while 循环

制作一个简单的游戏框架
输入1打印玩游戏,输入0打印退出游戏

参考代码:

#include <stdio.h>
int main()
{
	int n = 0;
	do
	{
		printf("*****************\n");
		printf("******1.play*****\n");
		printf("******0.exit*****\n");
		printf("*****************\n");
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			printf("玩游戏\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (n);
		return 0;
}

由于这是一个游戏,进入程序之后我们就要进入菜单了所以不需要判断就要直接进入一次循环体,所以这里使用do-while 循环更加合适。这个基本的框架在之后的猜数字游戏或是扫雷游戏中也会用到,在后续的博客中我也将为大家介绍这些游戏使用C语言如何实现。

4. break 和 continue 语句

在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了 break 和 continue 两个关键字,就是应该到循环中的。

• break 的作用是用于永久的终止循环,只要 break 被执行,就会直接跳出循环。
• continue 的作用是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所差异的。

4.1 while 循环中的 break 和 continue

4.1.1 break 示例
#include <stdio.h>
int main()
{
	int i = 1;
	while(i<10)
	{
		if(i==5)
			break;
		printf("%d ",i);
	} 
	return 0;
}

在这里插入图片描述
我们发现,正常的没有 break 语句的循环走下去应该在屏幕上打印1~10的数字,但是加上 break 语句后,当 i==5时break语句被执行,直接跳出循环,故打印1 ~ 4的数字。

4.1.2 continue 示例

如果我们把 break 语句改成 continue 语句会发生什么变化呢?

#include <stdio.h>
int main()
{
	int i = 1;
	while(i<10)
	{
		if(i==5)
			continue;
		printf("%d ",i);
		i++;
	} 
	return 0;
}

我们根据上面给出的 continue 的作用知道,当程序再屏幕上打印了1~4个数字之后,i==5,这时候再次进入到循环体,满足了 if 语句执行continue语句,continue会跳过本次循环中 continue 后面的代码,然后回到循环的判断部分也就是圆括号()内的语句,由于在上一次循环中跳过了i++,i ==5不变再次满足循环条件进入循环体,这时候我们发现,其实程序陷入了一个死循环。

4.2 for 循环中的 break 和 continue

4.2.1 break 示例

其实在 for 循环中 break 的用法与 while 中相同,只要执行 break 语句,循环将永久彻底终止。

#include <stdio.h>
int main()
{
	for( int i = 1;i <= 10;i++ )
	{
		if(i==5)
			break;
		printf("%d ",i);
	} 
	return 0;
}

在这里插入图片描述

4.2.2 continue示例

如果我们把 break 语句改成 continue 语句会发生什么变化呢?

#include <stdio.h>
int main()
{
	for( int i = 1;i <= 10;i++ )
	{
		if(i==5)
			continue;
		printf("%d ",i);
	} 
	return 0;
}

在这里插入图片描述
观察运行结果,在 for 循环中 continue 的作用是跳过本次循环中 continue 后的代码,直接去到循环的调整部分。未来当某个条件发生的时候,本次循环无需再执行后续某些操作的时候,就可以使用continue 来实现。

让我们对比一下 while 循环和 for 循环中 continue 作用的区别:
在这里插入图片描述

在这里插入图片描述

4.3 do-while 循环中的 break 语句和 continue 语句

do-while 循环中的 break 语句和 continue 语句 和 while 语句中几乎一模一样,所以这里不过多介绍。

4.4 循环嵌套

我们已经学习了三种循环语句:while 循环、for 循环、do-while 循环,当这三种语句互相嵌套使用时就叫做循环嵌套,这样就能帮我们解决更多更复杂的问题。下面我们看一个问题:

在屏幕上打印100~200之间的素数

分析问题:
1.打印100~200之间的素数首先我们需要产生100 ~ 200之间的数字。
2.素数的定义:一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数。
3.设一个自然数x == m * n,(m,n均为正数),则 m 和 n 都 <= √x ,这是一个简单的数学逻辑。
4.那么我们需要让100~200的数字去除以2 ~√x求余数,如果余数都不为0,则证明它不被1和它自身外的数字整除,它就是一个素数,于是我们还需要产生2 ~ √x的数字。

分析到这里之后我们对我们的程序或许有一定的思路,让我们尝试去写代码。

#include <stdio.h>
#include <math.h>
int main()
{
	for (int i = 100; i <= 200; i++)//产生100~200的数字
	{
		int flag = 1;//标志,1表示为素数
		for (int j = 2; j <= sqrt(i); j++)//产生2~sqrt(i)的数字
		//sqrt()是平方根,库函数,需要包含头文件<math.h>
		{
			if (i % j == 0)
			{
				flag = 0;//模为0,则不是素数
				break;//跳出单层循环,不继续进行比较
			}
		}
		if (flag == 1)
		{
			printf("%d ", i);//打印素数
		}
	}
	return 0;
}

4.5 goto 语句

除了 break 语句和 continue 语句外,C语言还提供了一种特殊的语法,goto语句和跳转标号。goto语句可以实现在同一个函数内跳转到指定的标号处。例如:

#include <stdio.h>
int main()
{
	printf("1 ");
	goto next;
	printf("2 ");
next:	
	printf("3 ");
	return 0;
}

程序运行结果:
在这里插入图片描述
我们发现程序在打印完1之后碰到了goto语句跳转到了next打印了3,将中间的2跳过。通过这个代码相信大家已经知道了goto语句的作用。
由于goto语句功能的强大,如果goto语句使用不当,容易导致在函数内部随意乱跳转,打乱程序的执行流程,甚至死循环。但它并非一无是处,在一个函数内有多层循环,循环内部break只能跳出break所在的一层循环,而goto语句可以任意跳转多层循环,在这种情况下使用goto语句将十分方便。

总结

循环语句到这里也介绍完毕,C语言—分支和循环语句到此就结束了,希望我的分享能给大家的学习带来一定的帮助,下期我将利用分支和循环语句的知识为大家带来一个简单的游戏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等你涅槃重生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值