【c语言】c语言分支与循环

1、C语言语句

c语言语句可分为以下几类
1.表达式语句
2.函数调用语句
3.控制语句
4.复合语句
5.空语句

在这里插入图片描述
又如控制语句,一般在分支与循环中较多使用
1.分支中如if语句、switch语句需要判断条件
2.循环中就如do while循环、while循环、for循环判断条件是否继续循环
3.还有一些break语句、continue语句、goto语句、return语句
这些均为控制语句,都是有某种条件成立才可继续执行下去的语句。
在这里插入图片描述

2、分支语句

分支语句是结构化的,其中有单分支和多分支
顾名思义,单分支即为只有一个分支组成,而多分支则有多个分支组成
这种结构化语言给我们带来众多便利

2.1、if语句

if语句有很多类型,请看下面代码

if(表达式)//if单分支语句if(表达式)
	;
else//if else语句
if(表达式1)
	;
else if(表达式2)else//像这样为多分支if语句

单分支示例
在这里插入图片描述

这里我解释一下,在if(表达式)语句中的表达式部分非0为真,0为假

多分支示例
在这里插入图片描述

2.1.1 悬空else

悬空else是什么意思呢?
我们在写if else多分支语句时常常碰到这种情况
下面我们就看一看是怎么回事吧!
如果你写了如下代码

在这里插入图片描述
你以为这串代码结果会是什么呢?
可能很多人张口就来,说会打印hehe
我说错,大错特错啊。
这串代码恰恰打印的是haha。
因为在if else 语句中,else只会和它离得最近的if相匹配,可称就近原则
所有可看出这串代码的else只会与第二个if相匹配,以至于结果出现了问题,
不能得到我们想要的结果。
第一个if后面跟的if else其实相当于一条语句,我们知道if语句只能控制一条语句
那如果我们想要得到我们想要的答案,怎么修改这串代码呢?
在这里插入图片描述
没错,只需要在if后面的if语句用{}括起来就行了。

2.1.2 if的常用书写形式对比

代码1

if(condition){
	return x;
}
return y;

代码2

if(condition)
{
	return x;
}
else
{
	return y;
}

代码3

int num = 1;
if(num == 3)
{
	printf("hehe\n");
}

代码4

int num = 1;
if(3 == num)
{
	printf("hehe\n");
}

代码4写成这样是为了如果我们把==写成=时,只有代码4才会报出相应错误,而代码3会认为你是在做赋值运算而不进行报错,很难发现错误所在。
如以上代码展示,很显然代码2和代码4更好,更容易理解。
建议我们以后要多些像代码2和代码4这种的代码风格。

2.1.3 练习

1.判断一个数是否为偶数
2. 输出1-100内所有偶数

#include<stdio.h>

int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 2 == 0)  //判断是否为偶数,利用对该数求余的方式,如果没有余数为0即为偶数
	{
		printf("该数是偶数\n");
	}
	return 0;
}
#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 100; i++)
	{
		if (i % 2 == 0)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

2.2、switch语句

switch语句也是一种分支语句
常常用在多分支的情况。
比如:

输入1,输出星期一

输入2,输出星期二

输入3,输出星期三

输入4,输出星期四

输入5,输出星期五

输入6,输出星期六

输入7,输出星期日

如果我们在这种情况下使用if else if else …这种多分支语句反而会显得太复杂了,所以我们引入了switch这种多分支语句。

switch(整型表达式)
{
	语句项;
}

语句项是什么呢?

case 整型常量表达式:
	语句;

2.2.1 switch语句中的break

switch语句不可或缺的break语句,只有带上break语句才能实现真正的分支
如下代码

#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;
	}
	return 0;
}

每次我们输入一个数就会进入相应的case下,执行对应语句,如果不使用break,将顺着该case往后一直执行到下一个break为止或者switch中该case后所有语句结束。
如果我们想同时几个case控制一些特定语句,如下

#include<stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	}
	return 0;
}

以上代码就可实现输入1-5输出weekday,输入6-7输出weekend。
(编程好习惯)在以后我们用switch语句时,相应的case语句的最后一个都要带上break结束语句,这样就会防止未来加入代码时忘记添加break。

2.2.2 switch语句中的default

在switch语句中如果输入的值和所有的case标签都不匹配时怎么办呢?
这时就需要一个能够处理除case标签以外的数据的子句,
这个子句就可以是default子句,default子句可以放置在switch语句中的任何位置,
把下面的标签可放在任何case标签可以出现的位置即可

default:

当switch中的所有case都匹配不上时就会进入default子句
所以每个switch语句只能有一个default子句
(编程好习惯)我们应该在每个switch语句中加入default子句,并且应该在每个default子句的最后加上break语句,这样就会防止出现一些错误。

2.2.3 练习

我们看下面代码运行结果会是如何,我们不妨自己算一下

#include <stdio.h>
int main()
{
	int n = 1;
	int m = 2;
	switch (n)
	{
	case 1:
		m++;
	case 2:
		n++;
	case 3:
		switch (n)
		{//switch允许嵌套使用
		case 1:
			n++;
		case 2:
			m++;
			n++;
			break;
		}
	case 4:
		m++;
		break;
	default:
		break;
	}
	printf("m = %d, n = %d\n", m, n);
	return 0;
}

上面这串代码进行了switch嵌套,可见switch也是可以嵌套使用的。
上面代码结果应是m = 5, n = 3。

3、循环语句

  • while
  • for
  • do while

3.1、while循环

我们前面已经了解if语句等分支与多分支部分,while循环跟if语句类似也是满足条件后执行接下来的语句,但不同的是while循环会执行多次其所包含的语句项生活中我们经常遇到一些事情我们要重复多次去做,而while循环正是这样,重复去做某件事情的语句。

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

该代码的作用就是在屏幕上打印1-10的数字
现在我们已经了解了while循环的基本语法,接下来再了解

3.1.1 while循环里面的break和continue

break介绍

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

这个代码执行下来就得不到1-10的数了,只能得到1-4的数就结束了

总结
其实在while循环中遇到break就会终止循环
所有break是可以永久的终止循环的

continue介绍

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

以上代码把break换上continue就出现了出乎意料的结果
依然可以打印1-4,但之后将进入死循环。
这是为什么呢?
原来是continue的作用,当打印1-4后判断i==5正确执行continue语句,会重新回到while后面的判断中不断这样循环下去,所有就出现了死循环。
那我们再看以下两串代码

//代码什么意思?
//代码1
#include <stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)
		putchar(ch);
	return 0;
}
//这里的代码适当的修改是可以用来清理缓冲区的.
//代码2
#include <stdio.h>
int main()
{
	char ch = '\0';
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch > '9')
			continue;
		putchar(ch);
	}
	return 0;
}
//这个代码的作用是:只打印数字字符,跳过其他字符的

3.2、for循环

> for(表达式1;表达式2;表达式3>		循环语句;

下面我们看看for循环的语法

3.2.1 语法

表达式1
表达式1为初始化部分,用于初始化循环变量的。
表达式2
表达式2为条件判断部分,用于判断循环时候终止。
表达式3
表达式3为调整部分,用于循环条件的调整。

使用for循环打印1-10的数

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{			//i = 1 - 初始化部分 i <= 10 - 判断部分 i++ - 调整部分
		printf("%d ", i);
	}
	return 0;
}
#include<stdio.h>
int main()
{
	int i = 0;
	//实现相同的功能,使用while
	i = 1;//初始化部分
	while (i <= 10)//判断部分
	{
		printf("hehe\n");
		i = i + 1;//调整部分
	}
	//实现相同的功能,使用for
	for (i = 1; i <= 10; i++)
	{
		printf("hehe\n");
	}
	return 0;
}

可以看出for循环相对while循环的优势是很明显的,while的初始化部分、判断部分、调整部分都相隔甚远不易观察,而for的三个部分集中在一起,非常方便使用,效率更高,所以for循环使用的频率是更高的。

3.2.2 for循环中的break和continue

请看如下代码示例

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

判断i == 5时执行break,运行结果
是,1-4
这个结果可能我们还是都能够猜到的,与前面学习的while循环类似。
如果是continue呢?

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

运行结果是1-4,6-10
我们发现这个结果和while循环的结果就相差很多了
这是为什么呢?
原因是在while循环中
在这里插入图片描述
经过判断后执行语句continue时不会在进行调整操作了,所以死循环产生
而for循环则不会发生这样的事情,continue只会终止它之后的语句。
在这里插入图片描述

3.2.3 for语句的循环控制变量

建议
1.不要在for循环内部改变循环变量,防止for循环失去控制
2.建议写成前闭后开的写法,这种写法更适合比如数组这种

#include<stdio.h>
int main()
{
	int i = 0;
	//前闭后开的写法
	for(i=0; i<10; i++)
	{}
	//两边都是闭区间
	for(i=0; i<=9; i++)
	{}
	return 0;
}

3.2.4 for循环的变种

第一个变种,如下代码

#include<stdio.h>
int main()
{
	int i = 0;
	for (;;)
	{
		printf("haha\n");	//for循环的初始化,判断,调整三部分都是可以省略的
							//可根据需要省略对应内容,但不建议初学者省略
	}
	return 0;
}

第二个是for循环可以嵌套使用,这个简单,就不多阐述了
第三个是

#include<stdio.h>
int main()
{
	//代码3
	int i = 0;
	int j = 0;
	//如果省略掉初始化部分,这里打印多少个hehe?
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe\n");
		}
	}				
	return 0;
}

将打印10个hehe,原来如果不省略的情况下是可以打印100个hehe的,为什么会出现这种情况呢?
这是因为当嵌套的for循环省略掉初始化部分后在第二次进入内部for循环时由于没有进行变量的初始化,将使用上次循环终止时的变量值而无法再次进入循环了。
第四个
for循环是可以用于两个或更多变量进行初始化,判断,调整的。

3.2.5 一道笔试题

//请问循环要循环多少次?
#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0;
}

这个笔试题其实就很简单了,我们如果了解了判断==和赋值=的区别就会很清楚,以及我们学到的for循环的语法知识,看上面代码,for循环的判断部分为k=0为赋值运行,所以该循环判断部分是衡为假的,故该循环为0次。

3.3、do while循环

3.3.1 语法

do
{
	循环体;
}while(条件表达式);

do什么意思?可以理解为做一件事情,首先去做,然后再判断后续可不可以继续做下去。
do while循环就是这样,先执行一次循环体再进行判断,如果为真再次执行循环体,这是do while循环的语法规则。

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

我们依然以打印1-10为例,可以明显发现do while循环的特点。
读者不妨下去动手试试看。

3.3.2 do while循环中的break和continue

我们前面已经讲了break和continue在while循环和for循环中的特点,下面我们看看do while中是什么样的把!
依然尝试下面这种代码

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

这串代码就更容易得出正确的答案了,一旦i增加到5就会执行break而跳出循环,程序结束。
答案:1 2 3 4
那如果是continue呢?

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

这串代码就可以发现continue的实际用法,如果当i增加到5,i反而不会再增加了,因为当执行continue时会直接跳过它之后的代码直接进行条件判断,而这样的话i会一直不再增加而为一固定的5,这将进入了1-4 后续为死循环

3.4、goto语句

在本章的最后还有一个有意思的语句,它就是goto语句。
goto语法结构就很简单,如下

flag:
	语句项;
	goto flag;
	语句项;
	goto flag;
	语句项;
flag:
	语句项;

看上面两串代码,无论标号在goto的什么位置,上面或者下面都可以通过标号找到对应位置执行下去。

  • goto语句常常在c语言被描述为可随意滥用和挑战标记的标号,可见goto语句在c语言中的名声可不是太好,那goto语句就没有过人之处了吗?

  • 理论上goto语句是没有必要的,很多程序不需要goto语句也能实现

  • goto语句更多的是在当有多层嵌套循环时,需要我们一次性跳出全部循环,那么goto语句就是神一般的语句呀

for (;;)
	{
		for(;;)
			for (;;)
			{
				if (condition)
					goto error;
			}
	}
error:
	if (condition)
		;

我们可以想象,如果有很多个循环,我们试用break的话,可见一个break是只能跳出一个循环的,而这么多循环我们要用多少个break?什么是很麻烦,而如果我们能用goto,是不是一下就跳出来所有循环,更快捷,方便,可见goto语句也是有过人之处的。
好了,本篇文章就到这里了,往三连支持一下,= =。

总结:
写到最后,也是废了作者九牛二虎之力写出了这篇拙文,希望各位读者能能多多指出问题所在,咱会继续努力的,感谢感谢观看。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花影随风_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值