首页 > 其他分享 >分支和循环

分支和循环

时间:2024-10-17 12:20:18浏览次数:3  
标签:语句 main int 循环 printf include 表达式 分支

分支和循环

C语言是一门结构化的程序设计语言,这里的结构指的是顺序结构选择结构(也可以叫做分支结构或条件判断结构)、循环结构。我们可以使用if语句、switch语句实现分支结构,用while循环、for循环、do while循环实现循环结构。

一、if语句

1.if

语法:

if(表达式)
    语句;

表达式成立(为真),则执行语句;表达式不成立(为假),则不执行语句。
C语言中,0为假,非0为真。即表达式为0,则不执行语句;表达式为非0,则执行语句。

例子: 输入一个整数,判断是否为奇数。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 2 == 1)
		printf("%d是奇数\n", num);
	return 0;
}

if语句的执行流程

2.else

如果一个数不是奇数,那就是偶数了。那么,输入任意一个整数时,该用什么方法判断它是奇数还是偶数呢?这时候就要用到if else语句了。

语法:

if(表达式)
    语句1;
else
    语句2;

例子: 输入一个整数,判断是否为奇数,如果是奇数则打印奇数,否则打印偶数。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 2 == 1)
		printf("%d是奇数\n", num);
	else
		printf("%d是偶数\n", num);
	return 0;
}

练习: 输入一个年龄,>=18岁就输出成年,否则就输出未成年。

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
		printf("成年\n");
	else
		printf("未成年\n");
	return 0;
}

3.分支中包含多条语句

默认在ifelse语句中都只控制一条语句。
例子:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
		printf("成年了\n");
	    printf("可以谈恋爱了\n");
	return 0;
}

我们发现,不管输入的值是>=18,还是<18,可以谈恋爱了都会被打印在屏幕上。
在这里插入图片描述
在这里插入图片描述
这是因为if语句只能控制一条语句:if语句的表达式成立(为真),则执行语句printf("成年了\n");;if语句的表达式不成立(为假),则不执行该语句。语句printf("可以谈恋爱了\n");是独立存在的,不论if语句的表达式是真是假,这条语句都会被打印在屏幕上。
若想让ifelse语句控制多条语句的话,那就要用大括号{}把代码块括起来。(被大括号括起来的多条语句叫做代码块/程序块,也叫做复合语句。)

例子:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age >= 18)
	{
		printf("成年了\n");
		printf("可以谈恋爱了\n");
	}
	else
	{
		printf("未成年\n");
		printf("不可以早恋哦\n");
	}
	return 0;
}

4.嵌套if语句

语法1:if else语句中的else与另一个if语句连用,构成多重判断。

例子: 输入一个整数,判断输入的数是0、是正数还是负数。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num > 0)
		printf("%d是正数\n", num);
	else if (num < 0)
		printf("%d是负数\n", num);
	else
		printf("是0\n");
	return 0;
}

背景为蓝色的代码是嵌套在前面的else语句中的:
在这里插入图片描述
语法2:if else语句里的if嵌套一个if语句。

例子: 输入一个整数,如果是正数,则再判断是奇数还是偶数,并输出;若不是正数,则输出非正数。

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num > 0)
	{
		if (num % 2 == 0)
			printf("%d是正数且是偶数\n", num);
		else
			printf("%d是正数且是奇数\n", num);
	}
	else
		printf("非正数\n");
	return 0;
}

背景为蓝色的代码是嵌套在前面的if里的:
在这里插入图片描述
练习:
输入一个人的年龄
如果年龄<18岁,则打印“少年”
如果年龄在18岁到44岁之间,则打印“青年”
如果年龄在45岁到59岁之间,则打印“中老年”
如果年龄在60岁到89岁之间,则打印“老年”
如果年龄在90岁及以上,则打印“老寿星”

较复杂写法:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
		printf("少年\n");
	else if (age >= 18 && age <= 44)
		printf("青年\n");
	else if (age >= 45 && age <= 59)
		printf("中老年\n");
	else if (age >= 60 && age <= 89)
		printf("老年\n");
	else
		printf("老寿星\n");
	return 0;
}

上述代码中,若表达式age < 18为假,则进入下一个else if语句中,所以这个else if语句暗含着表达式age >= 18,意味着表达式age >= 18可以省略不写。简化写法:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
		printf("少年\n");
	else if (age <= 44)
		printf("青年\n");
	else if (age <= 59)
		printf("中老年\n");
	else if (age <= 89)
		printf("老年\n");
	else
		printf("老寿星\n");
	return 0;
}

加上大括号更容易明白:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("少年\n");
	}
	else
	{
		if (age <= 44)
		{
			printf("青年\n");
		}
		else
		{
			if (age <= 59)
			{
				printf("中老年\n");
			}
			else
			{
				if (age <= 89)
				{
					printf("老年\n");
				}
				else
				{
					printf("老寿星\n");
				}
			}
		}
	}
	return 0;
}

5.悬空else问题

如果有多个if和一个else,那么else总是跟最近的if匹配。

例子:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hehe\n");
	else
		printf("haha\n");
	return 0;
}

结果是什么都没打印:
在这里插入图片描述
实际上,else是和第二个if语句匹配,后面的if else语句是嵌套在第一个if里的,若第一个if的表达式不成立,则嵌套在里面的if else语句就不会被执行,最终什么都不会打印出来。

如果代码改成这样就更好理解了:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
			printf("hehe\n");
		else
			printf("haha\n");
	}
	return 0;
}

若希望else与第一个if匹配,代码可以写成:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
			printf("hehe\n");
	}
	else
		printf("haha\n");
	return 0;
}

只要加上适当的大括号,代码的逻辑就会更加的清晰,所以写代码的时候注意括号的使用,就会让代码的可读性变高。

二、关系操作符/运算符

C语言里用于比较的表达式叫做“关系表达式”(relational expression)。关系表达式通常返回01,分别表示假或真,C语言里,0为假,非0为真,例如,20>19返回112>20返回0。关系表达式常用于ifwhile结构。

例子:

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

关系表达式中使用的运算符叫做“关系运算符”(relational operator),主要有下面六个:
>:大于运算符
<:小于运算符
>=:大于等于运算符
<=:小于等于运算符
==:相等运算符
!=:不相等运算符

下面是一些例子:

a > b;
a < b;
a >= b;
a <= b;
a == b;
a != b;
#include <stdio.h>
int main()
{
	int b = (3 == 5);
	printf("b=%d\n", b);
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int b = (0 == 0);
	printf("b=%d\n", b);
	return 0;
}

在这里插入图片描述
注1: 相等运算符==和赋值运算符=不一样,有的时候会把==误写成=,程序能运行,但运行结果会出乎意料。

例子:

#include <stdio.h>
int main()
{
	int x = 0;
	if (x = 3)
		printf("I like C\n");
	return 0;
}

在这里插入图片描述
上述示例中,代码原意是x == 3但是误写成了x = 3x = 3表示=右边的3赋值给=左边的x,所以这个式子的返回值为3(非0,为真),if判断总为真。

为了防止出现这种错误,可以把变量写在等号的右边。如果把相等运算符==写成赋值运算符=,编译器就会报错。

例子:

#include <stdio.h>
int main()
{
	int x = 17;
	if (17 == x)
		printf("seventeen is %d\n", x);
	return 0;
}
#include <stdio.h>
int main()
{
	int x = 17;
	if (17 = x)
		printf("seventeen is %d\n", x);
	return 0;
}

在这里插入图片描述**注2:**多个关系操作符不宜连用。

i<j<k

上述关系表达式中连用了两个小于运算符,这是合法表达式,不会报错,但是不会保证变量j的值在变量i和变量k之间。关系表达式是从左往右计算的,所以实际的表达式如下:

(i<j)<k

上面表达式中,i<j返回值为01,结果是01和变量k进行比较。若想判断变量j是否在变量ik之间,则用下列写法:

i<j && j<k

例子: 输入一个年龄,如果年龄在18岁到36岁之间,则输出青年。
如果这样写:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (18 <= age <= 36)
		printf("青年\n");
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就会发现,不管输入的值在不在18到36之间,都会输出青年。原因是关系表达式18<=age的返回值01总是小于36的,所以关系表达式18<=age<=36的返回值总为1,即总能输出青年。
正确的代码如下:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (18 <= age && age <= 36)
		printf("青年\n");
	return 0;
}

三、条件操作符/运算符

条件操作符是一个需要三个操作数的操作符,所以条件操作符又叫做三目操作符。形式如下:

exp1 ? exp2 : exp3

上述表达式中,若exp1(expression 1:表达式1)为真,则计算exp2,计算的结果为整个表达式的结果;若exp1为假,则计算exp3,计算的结果为整个表达式的结果。

练习1: 使用条件操作符表示下面代码的逻辑

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	if (a > 5)
		b = 3;
	else
		b = -3;
	printf("b=%d\n", b);
	return 0;
}

用条件操作符表示:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d", &a);
	b = a > 5 ? 3: -3;
	printf("b=%d\n", b);
	return 0;
}
}

练习2: 使用条件表达式找两个数中的最大值。

#include <stdio.h>
int main()
{
	int num1 = 0;
	int num2 = 0;
	scanf("%d %d", &num1, &num2);
	int max = num1 > num2 ? num1 : num2;
	printf("max=%d\n", max);
	return 0;
}

试着用if语句写写:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	int max = 0;
	scanf("%d %d", &a, &b);
	if (a > b)
		max = a;
	else
		max = b;
	printf("max=%d\n", max);
	return 0;
}

四、逻辑操作符/运算符:&&、||、!

逻辑运算符提供逻辑判断功能,主要有下面三个运算符:
逻辑与运算符&&:就是并且的意思,两侧的表达式都为真,则为真,否则为假。
逻辑或运算符||:就是或者的意思,两侧的表达式只要有一个为真,则为真,否则为假。
逻辑取反运算符!:改变单个表达式的真假。
注: C语言中,0为假,非0为真。

1.逻辑与运算符&&

在这里插入图片描述
&&是与运算符,就是并且的意思,&&是一个双目操作符,使用形式是a && b。只有&&两侧的表达式都为真,结果才为真,否则为假。

例子: 用代码表示月份从三月到五月是春天。

#include <stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month >= 3 && month <= 5)
		printf("春天\n");
	return 0;
}

2.逻辑或运算符||

在这里插入图片描述
||是或运算符,就是或者的意思,||也是一个双目操作符,使用形式是a || b||两侧的表达式只要有一个为真,则为真,否则为假。

例子: 用代码表示月份是12月/1月/2月是冬天。

#include <stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month == 12 || month == 1 || month == 2)
		printf("冬天\n");
	return 0;
}

3.逻辑取反运算符!

在这里插入图片描述
!是取反运算符,用于改变单个表达式的真假,!是一个单目操作符,使用形式是!a

例子:

#include <stdio.h>
int main()
{
	int a = 0;
	printf("a=%d\n", !a);
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int a = 8;
	printf("a=%d\n", !a);
	return 0;
}

在这里插入图片描述
定义一个变量flagflag为真,做一些事;flag为假,做一些事。

#include <stdio.h>
int main()
{
	int flag = 0;
	scanf("%d", &flag);
	if (flag)//flag为真,做一些事。
		printf("do something\n");
	return 0;
}
#include <stdio.h>
int main()
{
	int flag = 0;
	scanf("%d", &flag);
	if (!flag)//flag为假,那么!flag为真,做一些事。
		printf("do something\n");
	return 0;
}

4.练习:闰年的判断

输入一个年份year,判断year是否为闰年。
判断是否为闰年的规则:
(1)能被4整除并且不能被100整除是闰年。
(2)能被400整除是闰年。

法一:

#include <stdio.h>
int main()
{
	int year = 0;
	scanf("%d", &year);
	if (year % 4 == 0 && year % 100 != 0)
		printf("%d年是闰年\n", year);
	else if (year % 400 == 0)
		printf("%d年是闰年\n", year);
	else
		printf("%d年不是闰年\n", year);
	return 0;
}

法二:if(() || ())

#include <stdio.h>
int main()
{
	int year = 0;
	scanf("%d", &year);
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		printf("%d年是闰年\n", year);
	else
		printf("%d年不是闰年\n", year);
	return 0;
}

5.短路

逻辑运算符中的&&||有一个特点:它们总是先对左侧的表达式求值,再对右侧的表达式求值。
短路: 若逻辑运算符&&||的左侧表达式满足逻辑运算符的条件,就不用执行右侧表达式了。
短路求值: 仅仅根据左操作数的结果就能知道整个表达式的结果,而不用对右操作数进行计算的运算。

(1)与运算符&&

如前面的代码:

if (month >= 3 && month <= 5)

&&的左操作数为month >= 3,右操作数为month <= 5。若左操作数month >= 3的结果为0,则不用执行右操作数month <= 5,即整个表达式的结果为0
**结论:**对于与运算符&&来说,若左操作数的结果为0,则不用执行右操作数了,即整个表达式的结果为0

(2)或运算符||

如前面的代码:

if (month == 12 || month == 1 || month == 2)

month == 12的结果不为0,就不用再判断month是否等于1或2了,即整个表达式的结果为1
结论: 对于或运算符||来说,若左操作数的结果不为0,则不用执行右操作数了,即整个表达式的结果为1

练习: 阅读代码,计算代码输出的结果。

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("a = %d,b = %d,c = %d,d = %d,i = %d\n", a, b, c, d, i);
	return 0;
}

分析: 表达式a++ && ++b && d++中,先对左操作数a++进行计算:后置++,先使用,结果为0。后面的操作数就不用计算了,即整个表达式的结果为0,也就是i = 0。a使用完后+1,所以a = 1,b、c、d三个变量的值不变,所以最终输出内容为:
在这里插入图片描述
若把表达式a++ && ++b && d++换成a++ || ++b || d++

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
	printf("a = %d,b = %d,c = %d,d = %d,i = %d\n", a, b, c, d, i);
	return 0;
}

分析: 因为左操作数a++的结果为0,所以再看下一个操作数++b:前置++,先+1,b = 3;后使用,这个操作数的结果不为0。表明整个表达式的结果为1,即i = 1,那就不用计算后面的操作数了,也就是说变量c、d的值不变,a使用完后+1,所以a = 1,所以最终输出的内容是:
在这里插入图片描述

五、switch语句

switch语句是一种特殊形式的if else结构,用于判断条件有多个结果的情况,它把多重的else if改成更易用、可读性更好的形式。

switch (expression)
{
case value1:
	statement;
	break;
case value2:
	statement;
	break;
......
default:
	statement;
	break;
}

上面代码中,根据表达式expression不同的值,去执行相应的case分支,若没有找到对应的值,则执行default分支。
注:
(1)switch中的expression必须是整型表达式(int、short、long、long long、char,字符型有对应的ASCII码值)。
(2)case后的值必须是整型常量表达式

1.if语句和switch语句的对比

练习: 输入任意一个整数值,计算除3之后的余数。

若使用if语句:

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 3 == 1)
		printf("%d除3之后余数是1\n", num);
	else if (num % 3 == 2)
		printf("%d除3之后余数是2\n", num);
	else
		printf("%d除3之后余数是0\n", num);
	return 0;
}

若使用switch语句:

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	switch (num % 3)
	{
	case 0:
		printf("%d除3后余数为0\n", num);
		break;
	case 1:
		printf("%d除3后余数为1\n", num);
		break;
	case 2:
		printf("%d除3后余数为2\n", num);
		break;
	}
	return 0;
}

上述代码中,需要注意的点:
(1)case和后面的数字之间要有空格。
(2)每一个case语句中的代码执行完成后,要加上一个break;,这样才能跳出switch语句。

2.switch语句中的break

前面的代码中,若去掉case里的break;,会发生什么结果呢?

#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	switch (num % 3)
	{
	case 0:
		printf("%d除3后余数为0\n", num);
	case 1:
		printf("%d除3后余数为1\n", num);
	case 2:
		printf("%d除3后余数为2\n", num);
	}
	return 0;
}

在这里插入图片描述
可以发现,7除3的余数明明是1,但是多打印了余数是2这一行。原因是如果某一个case语句的后面没有break语句,代码会继续往下执行,直到遇到break语句或者switch语句结束。当然,不是每一个case语句都有break,这要根据实际情况来看。

练习: 输入一个1到7的数字,打印对应的星期几。

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期一\n");
		break;
	case 2:
		printf("星期二\n");
		break;
	case 3:
		printf("星期三\n");
		break;
	case 4:
		printf("星期四\n");
		break;
	case 5:
		printf("星期五\n");
		break;
	case 6:
		printf("星期六\n");
		break;
	case 7:
		printf("星期天\n");
		break;
	default:
		printf("输入错误\n");
		break;
	}
	return 0;
}

若需求发生变化:
(1)输入1到5,输出“工作日”。
(2)输入6或7,输出“休息日”。

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	default:
		printf("输入错误\n");
		break;
	}
	return 0;
}

3.switch语句中的default

当表达式expression没有找到对应的case分支时,要不就不做处理,要不就加一个default子句。

switch (expression)
{
case value1:
	statement;
	break;
case value2:
	statement;
	break;
default:
	statement;
	break;
}

switch后边的表达式expression的结果既不是value1也不是value2的时候,就会执行default子句。
前面打印星期的练习有用到default:若输入的数不是在1到7之间,则输出“输入错误”。下图中蓝色背景的代码就是。
在这里插入图片描述

4.switch语句中的case和default的顺序问题

其实,switch语句中的case语句和default语句没有顺序要求,但是通常是把default子句放在最后的。

六、while循环

1.if和while的对比

while语句的语法结构和if语句的非常相似:

if (表达式)
    语句;
while (表达式)
    语句;//若循环体想要包含更多的语句,可以加上大括号。

while语句和if语句的具体代码的对比:

#include <stdio.h>
int main()
{
	if (1)
		printf("hehe\n");//若满足if后面的条件,则打印一次hehe。
	return 0;
}
#include <stdio.h>
int main()
{
	while (1)
		printf("hehe\n");//若满足while后面的条件,则死循环打印hehe。
	return 0;
}

很显然,while语句是可以实现循环效果的,这就是它们的区别。

2.while语句的执行流程

在这里插入图片描述
先执行判断表达式,若表达式的结果为0,则直接跳出循环;若表达式的结果不为0,则执行循环语句,再执行判断表达式进行下一次的判断,判断是否进入下一次循环。

3.练习

练习1: 在屏幕上打印1到10的值。

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

在这里插入图片描述
练习2: 输入一个正的整数,逆序打印这个整数的每一位。
例如:
输入1234,输出4 3 2 1
输入564,输出4 6 5
题目解析:
(1)若想得到num的最低位,则可以用num % 10,例如1234 % 10为4。
(2)若想去掉num的最低位,则可以用num /= 10,例如1234 /= 10为123。123 % 10就能得到倒数第二位3。
(3)循环前两个步骤,在num变为0之前,就可以打印所有的位了。

#include <stdio.h>
int main()
{
	unsigned int num = 0;
	scanf("%u", &num);
	while (num)
	{
		printf("%d ", num % 10);
		num /= 10;
	}
	return 0;
}

七、for循环

for循环语句是在三种循环语句中使用最多的一个循环语句。

1.语法形式

for (表达式1; 表达式2; 表达式3)
	语句;//若循环体想要包含更多的语句,则要加上大括号。

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

2.for循环的执行流程

在这里插入图片描述
先执行表达式1初始化循环变量,再执行表达式2判断表达式,若表达式2的结果为假,则循环直接结束;若表达式2为真,则执行循环语句,再执行表达式3调整循环变量,最后再判断表达式,判断是否进入下一次循环。
整个循环的过程中,表达式1循环变量的初始化只被执行1次,只有表达式2、循环语句、表达式3在循环。

3.for循环的练习

练习1: 在屏幕上打印1到10的值。

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

在这里插入图片描述
练习2: 计算1到100之间3的倍数的数字之和。

#include <stdio.h>
int main()
{
	int i = 0;
	int sum = 0;
	for (i = 1; i <= 100; i++)//循环100次
	{
		if (i % 3 == 0)//判断100次
			sum += i;
	}
	printf("sum = %d\n", sum);
	return 0;
}

上述代码的优化:如果能直接产生3的倍数的数字,就省去了多余的循环和判断。

#include <stdio.h>
int main()
{
	int i = 0;
	int sum = 0;
	for (i = 3; i <= 100; i += 3)//循环30多次,没有判断
		sum += i;
	printf("sum = %d\n", sum);
	return 0;
}

4.while循环和for循环的对比

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

八、do while循环

在循环语句中,do while语句使用的最少。

1.语法形式

do
	语句;//若循环体想包含更多的语句,可以加上大括号
while (表达式);

whilefor这两种循环都是先判断,如果满足条件,则直接进入循环体,执行循环语句;如果不满足条件,则直接跳出循环。
do while循环是先直接进入循环体,执行循环语句,然后再执行while后面的判断表达式,若表达式为真,则进入下一次循环;若表达式为假,则不再继续循环。所以在do while语句中循环体是至少执行一次的,这是do while循环比较特殊的地方。

2.do while循环的执行流程

在这里插入图片描述

3.do while循环的练习

练习1: 在屏幕上打印1到10的值

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

或者:

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

在这里插入图片描述
练习2: 输入一个正整数,计算这个整数是几位数。
例如:
输入1234,输出4
输入78,输出2

#include <stdio.h>
int main()
{
	unsigned num = 0;
	int cnt = 0;
	scanf("%u", &num);
	do
	{
		cnt++;
		num /= 10;//这句和上一句cnt++可以互换位置
	} while (num);
	printf("cnt = %d\n", cnt);
	return 0;
}

这里并非必须使用do while语句,但是这个代码就比较适合使用do while循环,因为num即使是0,也是1位数,也是要统计的。
在这里插入图片描述

九、break和continue语句

在执行循环的过程中,遇到某些状况的时候,是需要提前终止循环的。C语言中提供了breakcontinue这两个关键字,就是应用到循环中的。
break在三种循环中的作用都是永久的终止循环。只要break被执行,break外的第一层循环就终止了,直接跳出该循环,继续往后执行。
continue的作用是跳过本次循环中的continue后面的代码。continuewhilefor这两种循环中的作用是有所差异的:在while循环中,执行完continue后直接进入循环的判断部分;在for循环中,执行完continue后直接进入循环的调整部分。

1.while循环中的break和continue

break举例

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

在这里插入图片描述
打印了1 2 3 4后,当i等于5时,遇到break,直接跳出break外的第一层循环,循环终止。

continue举例

上面的代码,把break换成continue会是什么结果呢?

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

在这里插入图片描述
上述代码中,打印了1 2 3 4,当i等于5的时候,执行continue,跳过本次循环中continue后面的语句,直接进入判断部分,由于跳过了i++,所以i一直是5,陷入死循环。显然,如果循环的调整部分是在continue之后,可能会造成死循环。

练习: 试写出下列代码在屏幕上打印的结果。

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

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

2.for循环中的break和continue

break举例

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

在这里插入图片描述

continue举例

上面的代码,把break换成continue会是什么结果呢?

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

在这里插入图片描述
所以在for循环中,continue的作用是跳过本次循环中continue后面的代码,直接进入循环的调整部分。

3.do while循环中的break和continue

do while语句中的breakcontinue的作用几乎和while语句中的一模一样。直接给出示例:

break举例

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

在这里插入图片描述

continue举例

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

在这里插入图片描述

十、循环的嵌套

前面学习了三种循环:whilefordo while,这三种循环往往会嵌套在一起使用,即循环的嵌套。
例子: 找出100到200之间的素数并打印在屏幕上。(素数:又称质数,只能被1和它本身整除的数)

法一:
找出100到200之间的素数,首先要有100到200之间的数,这里可以用循环解决。判断i是否为素数,可以拿2到i-1之间的数去试除i,需要产生2到i-1之间的数,这里也可以用循环解决。若2到i-1之间有能整除i的数字,则i不是素数;若都不能整除i,则i是素数。

#include <stdio.h>
int main()
{
	int i = 0;
	//int flag = 1;//错误写法,写在这屏幕上什么也没有
	for (i = 100; i <= 200; i++)//循环产生100到200之间的数字
	{
		int j = 0;
		int flag = 1;//假设i是素数
		for (j = 2; j <= i - 1; j++)//循环产生2到i-1之间的数字
		{
			if (i % j == 0)
			{
				flag = 0;//i不是素数
				break;
			}
		}
		if (flag == 1)
			printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
注: 不能把if(flag == 1)语句写成else语句放在前一个for循环里。例如,i等于102,j等于7,102 % 7 不为0,这时就会执行else语句,这样就会把102误认为是素数打印出来。错误写法:

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		int j = 0;
		int flag = 1;//假设i是素数
		for (j = 2; j <= i - 1; j++)
		{
			if (i % j == 0)
			{
				flag = 0;//i不是素数
				break;
			}
			else
				printf("%d ", i);
		}
	}
	return 0;
}

法二: n = a * b,其中a和b可不可能都大于根号n?很显然是不可能的,若都大于根号n,则a乘b的结果肯定是大于n的,这与等于n是矛盾的。所以,a和b至少有一个值是小于等于根号n的,如果n不是素数,那么一定有一个因子在2到根号n之间,也就是说,若2到根号n之间有能整除n的数字,则n不是素数;若都没有能整除的,则n是素数。

#include <stdio.h>
#include <math.h>
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		int j = 0;
		int flag = 1;
		for (j = 2; j <= sqrt(i); j++)
		//sqrt(i)表示根号i,sqrt()是库函数,需要包含头文件<math.h>
		{
			if (i % j == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag == 1)
			printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
在上述代码的基础上其实还能优化,我们知道偶数肯定不是素数,所以在第一个for循环上可以把偶数"过滤掉":

#include <stdio.h>
#include <math.h>
int main()
{
	int i = 0;
	for (i = 101; i <= 200; i += 2)
	{
		int j = 0;
		int flag = 1;
		for (j = 2; j <= sqrt(i); j++)
		{
			if (i % j == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag == 1)
			printf("%d ", i);
	}
	return 0;
}

十一、goto语句

goto语句可以实现在同一个函数内跳转到设置好的标号处。

例子:

#include <stdio.h>
int main()
{
	printf("hehe\n");
	goto next;
	printf("haha\n");
next:
	printf("hehe是呵呵\n");
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
again:
	printf("hehe\n");//死循环打印hehe
	goto again;
	return 0;
}

goto语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以建议是能不用尽量不用。但是,goto语句也不是一无是处,在多层循环的代码中,若想快速跳出,使用goto语句就非常方便了。

for (...)
{
	for (...)
	{
		for (...)
		{
			if (disaster)
				goto error;
		}
	}
}
error:
	//...

for循环想提前退出就要用break,一个break只能跳出一层循环,有三层循环的嵌套就要用三个break才能跳出循环,所以这种情况下用goto语句就会快捷点。

练习: 使用goto语句写一个关机程序。程序运行起来后,电脑将在一分钟后关机,但是,若输入:“人生是旷野,不是轨道”,就取消关机。

在搜索栏输入"cmd",然后点击"打开"
在这里插入图片描述
打开后如下图所示:
在这里插入图片描述
输入shutdown -s -t 60(关机倒计时60秒),系统会弹出电脑将在一分钟后关机的提示。
再输入shutdown -a(取消关机),系统会取消关机。
在这里插入图片描述
代码演示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	char input[20] = { 0 };//输入的字符串放进字符数组里
	system("shutdown -s -t 60");
again:
	printf("请注意,你的电脑将在60秒后关机,若输入;“人生是旷野,不是轨道”,就会取消关机。\n");
	scanf("%s", input);//输入的字符串就存储在input里
	if (strcmp(input ,"人生是旷野,不是轨道") == 0)
	{
		system("shutdown -a");
	}
	else
		goto again;
	return 0;
}

在这里插入图片描述
注:
(1)system()是一个库函数,这个函数是执行系统命令的,需要包含头文件<stdlib.h>
(2)字符串是不能使用==比较大小的,不能写成:input == "人生是旷野,不是轨道",应该使用strcmp()函数 - string compare,要包含头文件<string.h>strcmp()如果判断两个字符串相等,则返回0

上述代码也可以用while循环写:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");
	while (1)
	{
		printf("请注意,你的电脑将在60秒后关机,若输入;“人生是旷野,不是轨道”,就会取消关机。\n");
		scanf("%s", input);
		if (strcmp(input, "人生是旷野,不是轨道") == 0)
		{
			system("shutdown -a");
			break;
		}
	}
	return 0;
}

标签:语句,main,int,循环,printf,include,表达式,分支
From: https://blog.csdn.net/2401_87255690/article/details/142875588

相关文章

  • 双碳目标下基于遥感技术的碳储量、碳收支、碳循环等多领域监测与模拟实践技术应用
    卫星遥感具有客观、连续、稳定、大范围、重复观测的优点,已成为监测全球碳盘查不可或缺的技术手段,卫星遥感也正在成为新一代 、国际认可的全球碳核查方法。梳理碳中和与碳达峰对卫星遥感的现实需求,系统总结遥感技术在生态系统碳储量、碳收支、碳循环以及人为源排放反演等领域的......
  • 对带有指针类型的切片进行循环时避坑
    func(sp*scrapePool)sync(targets[]*Target){//加锁 sp.mtx.Lock() defersp.mtx.Unlock() var(//target标记 uniqueTargets=map[uint64]struct{}{}//采集周期 interval=time.Duration(sp.config.ScrapeInterval)//采集超时时间 timeout......
  • c语言分支和循环(上)
    1.if语句if语句后面不加分号,默认情况下if和else语句后面只能跟一条语句,如果要使用多条语句,可以用{}将想要多条表达的式子放进去#include<stdio.h>intmain(){intnum=0;//输入scanf("%d",&num);//一定别忘了取地址//判断和输出if(num%2==1)//......
  • 遥感技术在生态系统碳储量、碳收支、碳循环以及人为源排放反演等领域的技术发展
    以全球变暖为主要特征的气候变化已成为全球性环境问题,对全球可持续发展带来严峻挑战。2015年多国在《巴黎协定》上明确提出缔约方应尽快实现碳达峰和碳中和目标。2019年第49届 IPCC全会明确增加了基于卫星遥感的排放清单校验方法。随着碳中和目标以及全球碳盘点的现实压力,基于......
  • svn中的trunk是什么分支?
    在版本控制系统(如SVN、Git等)中,trunk是一个特殊的分支,通常用于表示主开发线。以下是trunk分支的一些关键点:1.定义Trunk:也称为主干或主分支,是项目的主要开发线。所有主要的开发工作通常都在trunk上进行。2.用途主要开发:开发人员在trunk上进行日常的开发工作,添加新......
  • 实验2 C语言分支与循环基础应用编程-1
    实验一:#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));cnt=0;while(cnt......
  • Java在for循环中修改集合
    前天看到一篇文章什么?for循环也会出问题?,里面涉及到在for循环中修改集合,想起来自己刚入行的时候就碰到过类似的问题,于是复现了一下文章中的问题,并试验了其它在循环中修改集合的方法。底层原理参考什么?for循环也会出问题?这篇文章的分析1.在fori中修改集合在fori中修改集合,不会......
  • Java在for循环中修改集合
    在Java中,ifPresent是一个用于Optional类型的方法,用于检查Optional对象中是否存在值并执行相应的操作。ifPresent方法接受一个Consumer函数式接口作为参数,如果Optional对象中包含值,则将该值传递给Consumer接口的实现方法。以下是ifPresent方法的使用示例:importj......
  • 单元格之间创建循环超链接01
    我们可以使用openpyxl库来操作Excel文件。以下是代码,展示了如何在指定的工作表中为具有相同值的多个单元格之间创建循环超链接安装openpyxl首先,确保你已经安装了openpyxl库。如果没有安装,可以使用以下命令进行安装:pipinstallopenpyxlimportopenpyxldefcrea......
  • LabVIEW智能可变温循环PCT测试系统
    LabVIEW智能可变温循环PCT测试系统随着科技的不断发展,实验室测试和质量控制已经成为科学研究和工业制造中不可或缺的一部分。在实验室测试中,PCT测试系统是一种常用的质量控制工具,通过测量材料的热传导系数来评估材料的性质。然而,传统的PCT测试系统需要手动调节测试温度和时间,......