【C语言】分支和循环语句

大家好,欢迎来到C语言的世界,今天想跟大家分享一下C语言的分支和循环语句,希望与大家一起学习和探讨。

一、什么是语句

C语言的代码是由一条又一条语句构成的,C语言中的语句可以分为以下五类:
1.空语句
2.表达式语句
3.函数调用语句
4.复合语句
5.控制语句
我们今天来探讨一下控制语句,控制语句是用于控制程序的执行流程,以实现程序的各种结构方式。
那什么是程序的各种结构方式呢?
C语言是一种结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构,C语言是能够实现这三种结构的。我们可以通过下图来加深我们对这三种结构的理解。
2.jpg
C语言有九种控制语句
1、条件判断语句也叫分支语句:if语句、switch语句;
2、循环执行语句:do while语句、while语句、for语句;
3、转向语句:break语句、goto语句、continue语句、return语句。

二、分支语句

1.if语句

if语句的语法形式如下:

//单分支
if ( 表达式 )
语句

//双分支
if ( 表达式 )
语句1
else
语句2

//多分支(嵌套if)
if ( 表达式1 )
语句1
else if ( 表达式2 )
语句2
else
语句3

表达式成立,即为真,则语句执行;表达式不成立,即为假,则语句不执行。
C语言中0为假,非0为真;也就是说当表达式的值为0时,语句不执行;表达式的值为非0时,语句执行。
例子:

#include <stdio.h>
int main()
{
    int num;
    scanf("%d", &num);
    if (num % 2 == 1)
        printf("奇数\n");
    else
        printf("偶数\n");
    return 0;
} 
#include <stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num == 0)
		printf("输入的数是0\n");
	else if (num > 0)
		printf("输入的数是正数\n");
	else
		printf("输入的数是负数\n");
	return 0;
}
1.1分支中包含多条语句

默认在if和else语句中默认都只控制一条语句
比如:

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

上面的代码我们原本希望奇数输出不可以被2整除和奇数两行,偶数输出可以被2整除和偶数两行,但我们运行后会发现结果报错,else没有匹配的if。
image.png
这也就是说if后只能控制一条语句,这时我们将if后的两条语句用括号括起来,成为一条复合语句

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

看看结果如何
image.pngimage.png
我们会发现当我们输入奇数时除了输出不可以被2整除和奇数,还会在最后一行输出偶数,这也就证明了else后也只能控制一条语句。同样也需要我们用括号将其变成一条复合语句。这样,才能达到我们想要的效果。改后的代码和结果如下:

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

image.pngimage.png

1.2悬空else

如果有多个if和else,else总是和最接近的if匹配。
我们来分析一下下面的代码结果

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 1;
	if (a == 1)
		if (b == 1)
			printf("好好学C语言\n");
	else
		printf("我要摆烂了\n");

	return 0;
}

如果我们不清楚else总是和最近的if相匹配这条规则的话,我们的答案应该是我要摆烂了。因为if中的表达式不成立,执行else的语句,那就是我要摆烂了。
但是,真实的结果是
image.png
啥也没有输出。为什么呢?
因为这个else并不是跟第一个if匹配而是,而是跟最接近的那个if,也就是if(b==1)相匹配;这个代码的风格是一种不好的风格,正因为他错误的排版,才容易导致我们将else与第一个if相匹配。所以,一个好的编程习惯是很重要的。
如果我们将代码改成下面这样就更加容易理解。

int main()
{
	int a = 0;
	int b = 1;
	if (a == 1)
		if (b == 0)
			printf("好好学C语言\n");
	    else
		    printf("我要摆烂了\n");
	return 0;
}

如果我们就是希望输出:我要摆烂了,也可以这样修改:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 1;
	if (a == 1)
	{
		if (b == 0)
			printf("好好学C语言\n");

	}
	else
		printf("我要摆烂了\n");
	return 0;
}

2.switch语句

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

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

switch语句会根据表达式expression不同的值,执行相应的case分支。如果找不到对应的值,则执行default分支。
注意:

switch后的expression必须是整型表达式
case后的值,必须是整型常量表达式,注意是常量,变量是不行的
case和后边的value之间必须有空格

例子:

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

结果:
image.png
我们不难看出每一个case语句中的代码执行完成后,都加上了break,那break有什么作用呢?不加对我们的结果是否产生影响?

2.1switch语句中的break

前面的代码中,如果我们去掉case语句中的break,会出现什么情况呢?

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

让我们看看运行后的结果:
image.png
我们发现后面多了两行,余数是1和2也都输出了,这是为什么呢?
原因是switch也是有分支的效果的,break翻译为打破,也就是说break可以打破这个分支,只有在switch语句中使用break才能跳出switch语句,如果某一个case后面没有break语句,代码会继续往下执行,有可能执行其他case语句中的代码,直到遇到break或switch语句结束。所以我们上面才会出现case1和case2的代码结果。
当然,也不是每个case都需要一个break语句,需要根据实际情况去分析。
练习:

输入一个1~7的数字,打印对应的星期几
例如:
输入:1 输出:星期一
输入:2 输出:星期二
输入:3 输出:星期三
输入:4 输出:星期四
输入:5 输出:星期五
输入:6 输出:星期六
输入:7 输出:星期日

代码如下:

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期一");
		break;
	case 2:
		printf("星期二");
		break;
	case 3:
		printf("星期三");
		break;
	case 4:
		printf("星期四");
		break;
	case 5:
		printf("星期五");
		break;
	case 6:
		printf("星期六");
		break;
	case 7:
		printf("星期日");
		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("工作日");
		break;
	case 6:
	case 7:
		printf("休息日");
		break;
	}
	return 0;
}
2.2switch语句中的default

当switch语句后面的expression的结果不是value1,也不是value2的时候,就会执行default语句后的代码。
正如我们上面的代码如果我们输入的不是1~7,那什么都没有输出,这时我们可以加一个default语句,来输出提示:输入错误。
我们可以这样来实现,代码如下:

#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日");
		break;
	case 6:
	case 7:
		printf("休息日");
		break;
	default: 
		printf("输入错误,请输入1-7的数字\n");
	}
	return 0;
}
2.3switch语句中的case和default的顺序问题

我们学到这里难免会有疑问,case和default句子有顺序要求吗,default只能放在最后吗?
答案是switch语句中的case语句和default语句是没有顺序要求的,只要你的顺序满足实际需求就可以了。
我们通常把default子句放在最后处理。
实践出真知,大家可以将上面代码中default和case语句进行更换,我相信代码是可以跑起来并且结果是一样的。

三、循环语句

1.while循环

while循环的语法结构跟if语句相似,区别是if语句条件满足执行一次,而while语句可以实现循环效果。

while(表达式)
语句;

如果循环体中想包含更多的内容,我们可以加上大括号。

1.1while语句的执行流程

1.3.jpg

1.2while循环的实践

练习:

在屏幕上打印1~10的值

代码如下:

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

2.for循环

2.1语法形式

for循环是三种循环中使用最多的,for循环的语法如下:

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

如果循环体想包含更多的语句,可以加上大括号;
表达式1用于循环变量的初始化;
表达式2用于循环结束条件的判断;
表达式3用于循环变量的调整。

2.2for循环的执行流程

1.4 (1).png
我们可以看到整个过程中,表达式1初始化部分只被执行1次,剩下的是表达式2、循环语句、表达式3在循环。

2.3for循环的实践

练习:

在屏幕上打印1~10的值

代码如下:

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

3.do-while循环

3.1语法形式

在循环语句中do-while循环语句的使用最少,它的语法如下:

do
语句;
while(表达式);

while和for这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;
而do-while循环则是直接进入循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。

3.2do while循环的执行流程

1.5.jpg
do-while语句中循环体至少执行一次,这是do while循环比较特殊的地方,也因此而被少用。

3.3do while循环的实例

练习:

在屏幕上打印1~10的值

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

4.break和continue语句

我们来看看break和continue的区别以及在循环中的作用
break的作用是用于永久的终止循环,只要break被执行,直接就会跳出循环,继续往后执行。
continue的作用是跳过本次循环continue后边的代码,在for循环和while循环中是有差异的。

4.1while循环中的break和continue

我们通过两段代码来看看在while循环中的break和continue是如何影响结果的
代码1:

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

结果为:
image.png
我们可以看到当i==5时,break永久的终止了循环。
代码2:

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

结果为:
image.png
我们可以看到结果一直没有结束,进入一个死循环,这是为什么呢?
因为当i=5后,就执行continue,直接跳过continue后边的代码,就去循环判断的地方,跳过了i = i + 1;所以i一直为5,程序陷入了死循环。

4.2for循环中的break和continue

我们同样也使用两段代码来看看
代码1:

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

结果为:
image.png
我们可以看到for循环跟while循环的break语句导致的结果都是一样的,当i=5时直接终止循环。
代码2:

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

结果为:
2012ce6f30c2212a77226112d133b1e.png
我们可以看到for循环中的continue也是跳过continue后面的代码,但是他的结果却跟while循环是不一样的,因为i++在for后面的表达式3,所以i并不会永远等于5,这就是他们的不同之处。

4.3do while循环中的break和continue

其实do while和while中的break和continue是一样的,我们可以看到他们实现的效果是一样的。
代码1:

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

结果为:
image.png
代码2:

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

结果为:
image.png

5.goto语句

C语言提供了一种特别的语法,就是goto语句和跳转标句,goto语句可以实现在同一个函数内跳转到设置好的标号处,但是注意要在同一个函数内。
例子:

#include <stdio.h>
int main()
{
	printf("我想要C语言的秘籍\n");
	goto next;
	printf("秘籍入口在此\n");
next:
	printf("你在想什么,好好学才是正道\n");
	return 0;
}

我们能否输出秘籍入口呢?
结果是:
image.png
看来还是要脚踏实地。我们不难看出goto语句如果使用不当,会导致其在内部随意乱跳转,打乱程序的执行流程。
但是,存在即合理,goto语句在一些多重嵌套中想要快速退出多重循环是很方便的,而break只能跳出当前这一层循环,而不能跳出多重循环。
最后,感谢大家跟我一起学习到了这里,大家可以自己打打代码,感受一下C语言的魅力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值