C语言:分支与循环语句

news2024/9/21 4:32:40

文章目录

    • 一.什么是语句
    • 二.控制语句
    • 三(一).分支语句if-else
      • 3.1if
      • 3.2if-else
      • 3.3if-else嵌套
      • 3.4悬空else
      • 3.5if语句判断的流程
      • 3.6if语句可能会犯的小错误
    • 三(二).分支语句switch
    • 四.循环语句
      • 4.1while语句
      • 4.2do while语句
      • 4.3for语句
      • 4.4一道简单又不简单的小题目
      • 4.5循环总结
    • 4.6循环上的一些小建议
    • 五.goto语句

一.什么是语句

C语言语句基本可以分为5类

  1. 表达式语句
    简单来讲就是一个以分号结尾的语句。
  1. 函数调用语句
    例如add();这就是调用了一个名字叫add的函数,这个就是函数调用语句
  1. 控制语句
    接下来讲的分支,循环语句就是控制语句
  1. 复合语句
    复合语句又称为语句块,把一堆语句用花括号括起来,形成一个单独的语句块
  1. 空语句
    就是一个分号,虽然有这个语句但是有和没有对程序没什么影响。
    一般用在循环里,可以当成一个空的循环体。
    也可以在以后调试设置在这里一个断点
    也可以在这里放一个空语句,以后想在这里插个新的代码,就可以能一下找到位置,也可以理解为增加代码可读性。

二.控制语句

控制语句又分三种:

1.条件判断语句也叫分支语句:if,switch语句

2.循环执行语句:do-while,while,for语句

3.转向语句:goto,break,continue,return语句

三(一).分支语句if-else

语法结构

//1.
if(表达式)
	语句;

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

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

当然也可以在一个if语句里在嵌套if语句

if(表达式)
	if(表达式)
	{}
else
	语句2;

3.1if

if(表达式)
	语句;

if就是如果的意思,后面跟的是一个表达式,整个代码的意思就是:如果这个表达式为真,就执行后面的这个语句。如果为假就不执行这个语句,代码就会跳过这个if,去执行之后的代码。

在C99标准出来之前,C语言是没有bool值这个概念的,if判断真假的方法是:
if后面的表达式的结果0就是假,非0即真
if后面的表达式的逻辑判断是真的话就是真,否则就是假

逻辑判断:

一个表达式判断是否为真,比较low的理解就是看这个表达式它有没有说谎,有就是假,否则就是真。

&&是逻辑与的符号:
表达式1 && 表达式2.只有两个表达式都为真的时候,这整个表达式的结果才是真,否则是假。你可以把它理解为乘法,结果为真就是1,为假是0.这样的话是不是只有1*1才是1,其它情况都是0.

||是逻辑或的符号:
表达式1 || 表达式2.只有两个同时为假,结果才是假,其它情况都为真。这里你可以理解为加法。当然这个的1+1结果还是1.

!是逻辑非的符号
!表达式。如果表达式是1,整个结果是0,否则就相反。

例子

int main()
{
	int i = 10;
	if (i == 10)
		printf("YES\n");
	return 0;
}

这句if代码的意思是如果i这个变量的值等于10就执行后面的这个printf函数。也就是i==10这个表达式结果为真就执行后面的语句。
在这里插入图片描述屏幕上确实打印了我们想要的YES。

\n
这个代表换行,就是输出完之后换一行,下次如果还想在屏幕上打印时就从YES下面那行开始写入信息。

=和==的区别:
一个=是赋值
a=20就是把20赋值给a,此时a的值就是20.
a=20这个语句结束后结果就相当于20.
a=21这个语句结束后的结果就相当于21.
两个=是判断相等
假入a的值现在是20.
a == 20这个结果就是1,也就是真。如果此时a的值是19呢?那刚才那个代码的值是假也就是0.

现在我通过两个代码来带大家理解逻辑为真,和结果为真有什么区别:

int main()
{
	int i = 0;

	if (i == 0)
	{
		printf("hello");
	}

	if (i = 0)
	{
		printf("hi");
	}
	return 0;
}

这个代码的结果是什么?
在这里插入图片描述

发现这里只打印了一个hello,那是因为第一个if判断的是i==0因为i的值的确为0,也就是说这个表达式的结果为真,所以可以打印if里面的内容。

那为什么第二个if语句里面内容没有被执行呢?那是因为这里不是判断,而是赋值i=0,说明把0这个值赋给i。赋值完之后if后面括号的内容就是:

if(0)

而在C语言中0为假,非0即真。所以不执行其里面的内容。

3.2if-else

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

现在我们希望给别人两种选择如果你选择了1就执行语句1,否则执行语句2.

int main()
{
	int i = 0;
	scanf("%d", &i);
	if (i < 18)
		printf("未成年");//语句1
	else
		printf("成年");//语句2
}

这个代码就是如果你输入的i值小于18,也就是if后面语句结果为真,就执行语句1.否则就执行语句2。

在这里插入图片描述
在这里插入图片描述假如我们现在语句1不止一句话:

int main()
{
	int i = 0;
	scanf("%d", &i);
	if (i < 18)
		printf("未成年");//语句1
		printf("666");//语句2
	else
		printf("成年");//语句3
}

像这样如果i < 18的值为真的话,程序会执行语句1和语句2吗?
在这里插入图片描述会发现不行,系统会报错,这是因为如果if语句下面没有加上花括号,if结果为真的时候系统不知道执行语句1,还是语句2.所以才会发生错误,所以我们这样改一下:

int main()
{
	int i = 0;
	scanf("%d", &i);
	if (i < 18)
	{
		printf("未成年");
		printf("666");
	}
	else
		printf("成年");
}

在这里插入图片描述现在就可以正常打印了。if,else后面只有一句代码时,可以省略掉{},但是为了养成两行的习惯,推荐不管后面有几句代码,都加上{}。

3.3if-else嵌套

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

你可以if,else,if…这样一直写,这根据你自己的需求来定。其实这段代码最开始是长这个样子的:

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

但是这样写可读性变得非常差,所以把它改成最上面的样子。这个语句可以帮我们写一个多分支的代码:

int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("少年\n");
	}
	else if (age >= 18 && age < 30)
	{
		printf("青年\n");
	}
	else if (age >= 30 && age < 50)
	{
		printf("中年\n");
	}
	else if (age >= 50 && age < 80)
	{
		printf("老年\n");
	}
	else
	{
		printf("老寿星\n");
	}
}

在这里插入图片描述

3.4悬空else

先看一段代码:

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hehe\n");
	else
		printf("haha\n");
	return 0;
}

这会打印哪个呢?可能有人脑子一热,a是0啊,if(a==1)结果为假肯定会执行下面的haha。但结果真是如此吗?
在这里插入图片描述发现什么都没有输出,这是为什么呢?因为如果一个else对应多个if时,这个else会去匹配离它最近的if。其实代码应该长这样:
在这里插入图片描述画方框的可以当成if(a == 1)里面的一个语句块。也就是说if(a = = 1)的结果为假的话,程序会跳过后面整个语句块。直接到return 0;所以程序什么也不会输出。
如果我们想要打印哈哈,就可以这样改:

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不是只会执行它后面的一个语句吗?上面这样写会不会出现问题?如果向下面这样写还有没有问题?

int main()
{
	int a = 0;
	int b = 2;
	if (a == 0)
		if (b == 1)
			printf("hehe\n");
		else
			printf("666\n");
	else
		printf("haha\n");
	return 0;
}

这里的if我没有加括号,但是我下面写了四行代码,现在它能不能执行打印666这个字符串呢?
在这里插入图片描述

运行结果上看是做的到的,为什么呢?不是是能执行一句吗?打印“666”都是第四句了,其实里面嵌套的if-else语句它可以当成一个语句,因为程序走到这一步的时候,if-else它只能进入到其中一个语句块中,另一个是不会进的。上面这个代码是进入到else语句,也就是说外面的if执行它后面的语句时是把else当成它的语句,而且进入到else之后不管else里面有多少行代码都不管了,都会执行,像这样:

int main()
{
	int a = 0;
	int b = 2;
	if (a == 0)
		if (b == 1)
			printf("hehe\n");
		else
		{
			printf("666\n");
			printf("666\n");
			printf("666\n");
			printf("666\n");
		}
	else
		printf("haha\n");
	return 0;
}

在这里插入图片描述

3.5if语句判断的流程

  1. 先执行if后面括号里的表达式或函数,得到结果
  2. 根据条件执行判断功能
  3. 最后在执行分支功能

什么意思呢?

int main()
{
	int a = 1;
	if (a == 0)
		printf("ah");
	else
		printf("a==1");
	return 0;
}

第一步先执行if后面的表达式拿到结果。

第二步在进行判断,判断是进入if还是else或者是if else的代码块当中。

第三步就是执行if/else里面的语句块。

3.6if语句可能会犯的小错误

有时候初学者可能会这样写代码:

int i = 0;
if(i == 0);
{
	printf("hello");
}

这样写是对的吗,当然是对的,但是这代码能得到你希望的值吗?那就不一定了,这里的错误就是习惯给一句代码后面加上分号。if后面本来是不需要加分号的,而这里你给加上了,如果你有一个很长的代码,这个地方出现了这样的一个小错误,而且更要命的是编译器还检查不出来这样的错误,以后找BUG就会花相当长的时间。

这里就是给大家提个醒,防止你们这样写。

还有一个小错误:

int i = 0;
if(i = 0)
{
	printf("hello");
}

这里把==写成了=,这样写编译器也同样检查不出来。所以为了避免出这样的错误,我比较推荐下面这种写法:

int i = 0;
if(0 == i);
{
	printf("hello");
}

这样反过来写,如果你少写一个等于号,编译器就会直接报错的。

三(二).分支语句switch

switch(整型表达式/整型)
{
	//语句项
	//一些case语句:
	case 整形常量表达式:
	语句;
}

这种case语句可以有很多个。举个例子:

int main()
{
	int day = 4;
	switch (day)
	{
	case 1:
		printf("星期一\n");
	case 2:
		printf("星期二\n");
	case 3:
		printf("星期三\n");
	case 4:
		printf("星期四\n");
	case 5:
		printf("星期五\n");
	case 6:
		printf("星期六\n");
	case 7:
		printf("星期天\n");
	}
	return 0;
}

这里的意思就是,先看switch后面的整型表达式结果是多少,是1的话就从case 1:后开始执行就是打印星期一,表达式是2就执行case 2:后面的内容打印星期二…但是这样写还少了些东西导致结果和我们希望的不一样。
在这里插入图片描述发现如果day的值是4的话,我们本希望它能打印星期四,但是它把星期五,六,天的都打印出来了。这是因为程序只是把case 4:当成入口,这个程序的出口则是在switch语句里面的这个语句块末尾因为switch不像if语句那样有判断和执行功能,它只有判断功能。所以我们希望在打印完星期四后就停止,所以加上限制条件:

int main()
{
	int day = 4;
	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;
}

这里加上break的限制条件。break的意思是程序运行到这里的时候,终止运行,程序会跳出这个程序块,执行switch后面的语句。break就是上面讲的控制语句里的转向语句的其中一种。

小总结一下:

switch语句只有判断功能,没有分支功能,switch只不过是拿着后面的整形表达式来一个一个与后面的case相比较,比较成功了就进去,换句话说switch语句中switch只起到一个类似寻找的功能将switch后面的结果和case一个一个比较,而真正的判断功能是case来实现。但因为switch语句里没有分支功能(只执行某一个语句块的功能),执行到相应case的代码块后会不断继续向下进行直到结束,所以这里需要加break来进行一个分支功能。

但是switch语句还有一个新的语句default语句,这个有什么用呢?假如此时我们的变量day是9:
在这里插入图片描述发现什么都没有输出,但是我们希望输入的数字不是1-7时想要输出一个“输入错误”,这时候就要用到default了。

int main()
{
	int day = 9;
	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");
	}
	return 0;
}

把default加在最后面,意思是上面的case都不是入口的话,就全执行default后面的代码。

这里有一个小建议:

每个switch-case后面都加一个default语句,即使你这个代码不需要它。

现在还有一个小拓展,如果我希望星期一~星期五输出工作日,星期六,日是休息日,其它就是输入错误,该如何改呢?

int main()
{
	int day = 3;
	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");
	}
	return 0;
}

这里有好理解了,如果day=1~5的时候不管从哪个入口进入,都是执行依次printf函数然后退出。

可能会出错的问题:

case后面的语句块不需要加花括号。当然加了也没什么问题。
每个case后面的不是分号而是冒号。

补充(一)

整型表达式:
首先整型是int,short,long,long long,char这些。表达式就是平常经常接触的加减乘除,逻辑运算,移位运算…这些。而整形表达式就是这些表达式运算时类型必须是整型。
上面switch后面跟的是整型或整形表达式。其实大部分都是整型,因为整型表达式的结果还是整型。

整型常量表达式:
限制条件比整形表达式还多一点,不仅要求你是整型,你还必须是常量,如果case后面是个变量就会出问题。

补充(二)
有没有可能会写下面这种代码,就是在case语句里面定义变量?

int main()
{
		int day = 9;
		switch (day)
		{
		case 1:
			int i = 10;
			printf("星期一\n");
			printf("星期一\n");
			printf("星期一\n");
			printf("星期一\n");
			printf("%d\n", i);
			break;
		default:
			printf("输入错误\n");
		}
		return 0;
}

运行一下会发现有报错。
在这里插入图片描述

说明case里面本身是不能定义变量的,但如果你非要去定义它也是可以的:

int main()
{
	int day = 1;
	switch (day)
	{
	case 1:
	//在case和break之间加上括号
	{
		int i = 10;
		printf("星期一\n");
		printf("星期一\n");
		printf("星期一\n");
		printf("星期一\n");
		printf("%d\n", i);
	}
	break;
	default:
		printf("输入错误\n");
	}
	return 0;
}

在这里插入图片描述

当然本身肯定是不建议这样写的,你需要定义一个变量,完全可以放在外面定义,但是如果非要在里面定义,最后将case里面代码封装成一个函数,然后在调用。像这样:

void show()
{
	int i = 10;
	printf("星期一\n");
	printf("星期一\n");
	printf("星期一\n");
	printf("星期一\n");
	printf("%d\n", i);
}

int main()
{
	int day = 1;
	switch (day)
	{
	case 1:
		show();
	break;
	default:
		printf("输入错误\n");
	}
	return 0;
}

补充(三)

default语句一定要放在最后吗?答案不是,你可以把它放在任意位置甚至是第一个case语句上面都是没问题的,不影响你的结果。

补充(四):
不推荐将break换成return,这个随便看看就行吧,一般switch语句都是用break来结束,你非要跟别人与众不同,这不是一个好的编码习惯。

补充(五)
不推荐switch后面的常量表达式写成bool类型的判断:

int a = 0
switch(a == 0)//像这种判断是不推荐的,虽然编译器不会报错
{}

补充(六):

既然case后面跟的需要是一个常量,这个常量可以是const修饰的变量吗?

int main()
{
	const int day = 1;
	switch (day)
	{
	case day:
		printf("星期一\n");
		break;
	default:
		printf("输入错误\n");
	}
	return 0;
}

答案是不行的:
在这里插入图片描述

这是因为const修饰的变量虽然强制变成了常量,但是它的本质还是变量。

补充(七)

推荐switch-case语句的规范:

  1. case后面的常量推荐用一定的顺序来写:a,b,c…或者1,2,3…这些。如果匹配的数据不是这些可以尝试用宏,枚举常量替换。
  2. 推荐将匹配正常的放在前面,匹配异常的放在后面如default.
  3. 推荐按匹配的频率放在前面,比如case 2:要匹配的频率很大,最后将这个case放在最前面,来提高效率。

上面这些通过不同场景来自行更改。

  1. 尽量简化每种case后面的内容,如果很多可以尝试用函数封装起来。
  2. 把每个需要匹配的case都写出来,比如星期一~星期六如果你想偷点懒将星期天这个结果扔给default也是不好的。最好是把每个结果都写出来,将其他默认结果扔给default.

四.循环语句

4.1while语句

while(表达式)
	循环语句;

这里的表达式真就会一直执行里面的循环语句,知道表达式的结果变成假才结束。

举个例子:

int main()
{
	int i = 5;
	while (i--)
	{
		printf("hello\n");
	}
	return 0;
}

大概流程是先判断while里面的表达式是否为真发现是5然后5–变成4,然后执行里面的printf语句,执行完之后又回去while那里看是不是真…这样一直循环直到while里面的表的式变成0,也就是假的时候结束。
在这里插入图片描述
现在在写一段代码:

int main()
{
	int i = 0;
	while (i < 10)
	{
		if (i == 5)
		{
			break;
		}
		printf("%d ", i);
		i++;
	}
	return 0;
}

看结果:
在这里插入图片描述发现break在while里面也同样适用,i==5为真的时候就跳出去。
现在我们再来看一个新的语句:continue

int main()
{
	int i = 0;
	while (i < 10)
	{
		if (i == 5)
		{
			continue;
		}
		printf("%d ", i);
		i++;
	}
	return 0;
}

再看一下这个代码会执行什么效果:
在这里插入图片描述这里不好展示,其实是代码执行到5时,一直卡在这里造成了死循环。continue是代码执行到这里的时候直接返回到最开始的while那里判断,continue后面的代码就不会被执行。注意这里回到的是while判断的那个地方,而不是回到循环内部的第一句。
在这里插入图片描述

上面的代码就会导致当i为5的时候,进入if语句走到continue然后跳回到while那里,就这样一直重复造成死循环。所以我们把刚才的代码稍微改一下:

int main()
{
	int i = 0;
	while (i < 10)
	{
		i++;
		if (i == 5)
		{
			continue;
		}
		printf("%d ", i);
	}
	return 0;
}

把i++移到上面去看看效果:
在这里插入图片描述发现打印的时候直接跳过了5.

上面写的那么多代码就是为了更好的理解continue的用途。

小总结:break和continue

break在循环语句里的作用是跳出循环/跳出当前语句块,在switch语句是跳出switch语句。
continue是遇到这个语句,就是不执行continue后面的内容,而是回到循环最开始的地方也就是判断的地方,重新开始。

这里要注意的是break只能在循环语句:while,do while,for和选择语句:switch中使用。
continue只能在循环语句里使用。

4.2do while语句

do while的用法:

do
循环语句;
while(表达式);

这个和while循环大同小异,while语句是先判断如果为真才执行里面语句,do while是什么都不管,先执行一次循环,在去判断while里面的表达式,如果为真就进循环,否则就退出。写个例子:

int main()
{
	int i = 0;
	do
	{
		i++;
		if (i == 5)
			continue;
		printf("%d ", i);
	} while (i < 10);
	return 0;
}

先执行循环,i++然后判断在打印出来,而遇到5的时候和while语句一样跳过,回到while判断部分。所以这个代码打印1-10中除了5的数字。
在这里插入图片描述

同理不要搞混了continue执行之后回到的位置:
在这里插入图片描述

4.3for语句

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

表达式1:
表达式1为初始化部分,用于初始化循环变量的。

表达式2:
表达式2为条件判断部分,用于判断循环时候终止。

表达式3:
表达式3为调整部分,用于循环条件的调整。

我直接来举个例子:

int main()
{
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

第一部分是初始化变量i,说明循环将从i为0开始判断,后面的流程我用图来表示:
在这里插入图片描述这样写的好处是把调整部分和判断部分放在了一起。不像while那样,调整部分写在循环体内。while里面的内容很多的时候,就很容易把人搞得晕头转向。

同理break,continue在for循环里同样适用,且用法一样。

for循环里面的这三部分,都可以省略不写,但是初学者不建议这样,容易出错。

for循环里面的控制条件也可以不止一个

int main()
{
	int x, y;
	for (x = 0, y = 0; x<2 && y<5; ++x, y++)
	{
		printf("hehe\n");
		return 0;
	}
}

小补充

学习上面的while,do-while语句可以知道,里面用continue语句的时候是回到条件判断处也就是while后面括号那里。但是for循环也是一样吗?向下面这个代码:

int main()
{
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("continue before : %d\n", i);
		if (i == 2)
		{
			printf("continue\n");
			continue;
		}
		printf("continue after : %d\n", i);
	}
}

程序运行到continue后是回到条件判断出:i<4。还是回到i++处呢?当然和while它们一样不会回到循环内部第一句的地方。

假设回到的是i<4的这个地方,但是看看我上面画的那个流程图可以发现回到i<4那个地方之后进行判断,如果为真会继续执行循环内部程序,也就是说这样写会造成一个死循环因为此时的i始终为2,因为没有机会到达i++这个地方。但事实是如此吗?
在这里插入图片描述

运行一下发现,没有死循环,正常结束,再仔细看打印continue后继续打印了两行,而且后面的那个数字变成了3,也就是说明在运行到continue后i++了一次,这不就说明了for语句中遇到continue会回到条件更新那个地方而不是条件判断这个地方:
在这里插入图片描述

但是如果,你的for循环是这样写的呢?

for(int i = 0; i < 5;)
{
	i++;
	if(i == 2)
		continue;
}

直接说结论,如果for语句后面没有条件更新这个部分,运行到continue会直接执行条件判断也就是i<5这一部分的。

4.4一道简单又不简单的小题目

int main()
{
	int i = 0;
	int k = 0;
	for(i =0,k=0; k=0; i++,k++)
		k++;
	return 0;
}

这里最大的坑就是for循环里的判断部分,这里是只有一个=,说明这是个赋值语句,把0赋值给k说明这个语句的结果就是0,为假。所以这个循环一次都不执行就退出来了。

4.5循环总结

循环中除了死循环一般都要包含三种条件:

1.循环初始化
2.循环判定
3.循环更新

int main()
{
	int count1 = 10;  //循环初始化
	while (count1 > 0)//循环判定
	{
		printf(".");
		count1--;     //循环更新
	}

	printf("\n");

	//   循环初始化        循环判定  循环更新
	for (int count2 = 10; count2 > 0; count2--)
	{
		printf(".");
	}

	printf("\n");

	int count3 = 10; //循环初始化
	do
	{
		printf(".");
		count3--;    //循环更新
	} while (count3 > 0); // 循环判定

	return 0;
}

一般死循环的写法:

int main()
{
	while (1)
	{
		printf(".");
	}

	for (;;)
	{
		printf(".");
	}

	do
	{
		printf(".");
	} while (1);

	return 0;
}

4.6循环上的一些小建议

  1. 如果在写循环嵌套的时候,如果可以尽量把循环次数多的放在内层,如果做不到也没事,就是一个小建议。因为这样可以避免在多层循环中跳转的次数。
  2. for循环写的时候尽量使用前闭后开区间的写法,向下面这样:
//[0,10)前闭后开区间
for(int i = 0; i < 10; i++)

这样写可以一眼看出来循环体要执行10次。如果是前闭后闭呢?

//[0,9]前闭后闭区间
for(int i = 0; i <= 9; i++)

上面这个虽然也是循环10次,但是观察的时候没有第一种直观。

  1. 这个了解一下就行,for循环判断的时候尽量不要用浮点型,因为浮点型可能会造成一些精度损失。

五.goto语句

这个语句比较简单:

start:
printf("1");
printf("1");
printf("1");
goto start;

上面start就是一个标签,这个名字由你随意去定,当程序运行到goto start的时候,程序会蹦到start:这个位置继续向下执行,上面这个代码就相当于一个死循环了。

goto语句只要在当前所在的代码块里,不管标签位置在哪都可以蹦过去。但是出了当前的代码块运行就会出错,向下面这个:

void test()
{
start:
	printf("goto test");
}

int main()
{
	goto start;
	return 0;
}

再来看看错误结果:
在这里插入图片描述

因为它在一个代码块里哪里都能去,如果用多了可能会因为粗心导致的错误,而且你还很难找到这个错误,同理这样写对代码的可读性也减少了。

所以说尽量少用,下面我随便写一个应用场景:

int main()
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			for (int k = 0; k < 10; k++)
			{
				if (k == 5)
					break;
			}
		}
	}
	printf("hello\n");
	return 0;
}

像这样我希望k为5的时候就跳出循环打印hello,这只加一个break能成功吗?当然不行一个break只能跳出一个for循环,这里要真的跳出去还需要在其它for循环里再加break,但是如果其它循环还有其它代码,这种操作又会变得很危险,所以在跳出多个循环语句的时候goto是给很方便的东西:

int main()
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			for (int k = 0; k < 10; k++)
			{
				if (k == 5)
					goto end;
			}
		}
	}
end:
	printf("hello\n");
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/80188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Opencv中关于特征点匹配定位的问题(一)DMatch解析

Opencv中关于特征点匹配定位的问题回顾定位回顾 在我们检测到特征点之后&#xff0c;通常进行特征点的匹配。 首先我们先回顾一下使用Brute-Force匹配器来进行匹配。 import cv2 import numpy as np import matplotlib.pyplot as plt#读取图片 imgcv2.imread(./newmm.png) te…

宝藏软件Obsidian知识体系搭建,免费的多端云同步

宝藏软件Obsidian知识体系搭建&#xff0c;免费的多端云同步。 为什么推荐Obsidian 人很奇怪,在关注短期目标的时候,会有成功失败之说,但是如果关注体系呢&#xff1f;就不那么会在乎短期收益了. 为什么呢&#xff1f;因为体系可能会创造强大的滚雪球效应. 使用笔记软件颇多…

如何针对时间片论法进行优化

前言 通过该篇学习了嵌入式的任务调度&#xff08;即时间片论法&#xff09;后&#xff0c;了解到通过以1ms为调度时间单位轮询判断是否需要执行函数任务&#xff0c;那么下面介绍如何基于时间片论法的任务调度模式充分利用MCU的资源&#xff0c;姑且先称这种方式为时间片差分…

一致性hash算法

目录 1.业务场景 2.传统hash算法 2.一致性hash算法 2.1.算法过程 2.1.一直性hash算法的优点 2.2.一致性hash算法的缺点 2.3.hash倾斜的解决办法 1.业务场景 假设有30000张图片需要存放到编号为1、2、3的3台服务器上。 2.传统hash算法 假设有30000张图片需要存到3台服务器…

【JavaWeb开发-Servlet】拾起海中的漂流瓶增强版

目录 原版&#xff1a; 1、前端样式 2、错误提示 3、实现id序列增长 完整项目代码&#xff1a; 原版&#xff1a; 【JavaWeb开发-Servlet】拾起海中的漂流瓶_代码骑士的博客-CSDN博客需求&#xff1a;点击网页按钮随机显示一句话&#xff1a;1、内容涵盖&#xff1a;老人…

PySpark大数据计算教程

PySpark大数据计算教程 了解如何将 Spark 与 Python 结合使用&#xff0c;包括 Spark Streaming、机器学习、Spark 2.0 DataFrames 等&#xff01; 课程英文名&#xff1a;Spark and Python for Big Data with PySpark 此视频教程共4.0小时&#xff0c;中英双语字幕&#xf…

多模态(红外,可见光)目标检测

【github】https://github.com/DocF/multispectral-object-detection 一.环境 1.1 环境 基本依赖和yolov5基本相同&#xff0c;当然也可以配置在虚拟环境中 git clone https://github.com/DocF/multispectral-object-detection cd multispectral-object-detection pip ins…

基于燃压缩空气储能系统的零碳微能源互联网优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f468;‍&#x1f4bb;做科研&#xff0c;涉及到一个深在的思想系统&#xff0c;需要科研者逻辑缜密&#xff0c;…

由美国火星照片细节,分析造假的疑点

穿帮都是细节。 除了阿波罗登月&#xff0c;你觉得美国还在哪些航天项目中有造假嫌疑&#xff1f; - 知乎 西红柿加醋 能走着游泳就好了 ​ 关注 无可靠信息来源 423 人赞同了该回答 除了登月&#xff0c;比较又争议的当然就数登火了&#xff0c;比如出自Nasa官方网站上的…

CSS布局-定位,相对,绝对,子绝父相,固定定位,层级关系。

CSS布局-定位&#xff0c;相对&#xff0c;绝对&#xff0c;子绝父相。 目录CSS布局-定位&#xff0c;相对&#xff0c;绝对&#xff0c;子绝父相。1、定位1.1 网页常见布局方式1.2 定位的常见应用场景2.1 定位初体验2.2 使用定位的步骤3.1 静态定位4.1 相对定位5.1 绝对定位5.…

矩阵理论复习(五)

2004年试题 Hermite矩阵酉相似于对角阵 验证相容矩阵范数 盖尔圆盘互不相交&#xff0c;则特征值都不相同&#xff0c;若盖尔圆盘全部出现在右半复平面上&#xff0c;则特征值全为实数。 矩阵二范数的计算 最大秩分解M-P广义逆矩阵方程是否有解 2005年试题 正定矩阵&a…

【秒杀购物商城业务服务】「分布式架构服务」盘点中间件服务的高可用模式及集群技术的方案分析

秒杀购物商城业务服务-分布式架构介绍 基于MySQL数据库集群技术实现服务的高可用基于Tomcat的集群负载机制实现Tomcat服务器的高可用基于Nginx负载均衡机制实现负载均衡&#xff08;介绍和配置&#xff09;基于Redis缓存服务实现数据缓存控制相关介绍和技术点分析 基于MySQL数…

RTC 时钟电路如何选择法拉电容的容量

理论依据&#xff1a; 公式 1&#xff1a;Q I * t 公式 2&#xff1a;Q CU 由此推导出→I * t CU →t CU/I(将根据这个计算时钟保留时长) 说明 Q&#xff1a; 电荷量 &#xff08;单位&#xff1a;库仑&#xff09;I&#xff1a; 电流 &#xff08;单位&#xff1a;安培&a…

QT/C语言 实现数据库sqlite3

QT/C语言 实现数据库sqlite3【1】引入数据库【2】下载移植sqlite31.移植sqlite32.使用sqlite33.sqlite3中的数据类型4.常用的SQL语句(全部都是分号结尾)(1)新建表格(2)往表格中插入数据(3)查询表格中的数据(4)删除表格中的数据(5)修改表格中的数据【3】C语言调用sqlite31.接口函…

第10部分 DHCP

目录 10.1 DHCP 概述 10.2 实验1&#xff1a;DHCP 基本配置 1.实验目的 2.拓扑结构 3.实验步骤 4.实验调试 &#xff08;1&#xff09;在客户端测试 &#xff08;2&#xff09;show ip dhcp pool &#xff08;3&#xff09;show ip dhcp binding 10.3 实验&#xff…

LeetCode 1827. 最少操作使数组递增

最少操作使数组递增 简单 46 相关企业 给你一个整数数组 nums &#xff08;下标从 0 开始&#xff09;。每一次操作中&#xff0c;你可以选择数组中一个元素&#xff0c;并将它增加 1 。 比方说&#xff0c;如果 nums [1,2,3] &#xff0c;你可以选择增加 nums[1] 得到 nums …

实战讲解Spring定时任务:@Scheduled(图+文+源码)

1 缘起 最近看到有些定时任务的项目&#xff0c; 使用了Spring自带的定时任务系统&#xff0c;通过添加Scheduled注解的方式实现&#xff0c; 并且&#xff0c;使用了不只cron表达式的方式实现定时执行&#xff0c; 恍然大悟&#xff0c;原来Scheduled还有其他的方式实现定时任…

《小猫猫大课堂》3之字符串,转义字符,注释,选择和循环语句,函数等小概括。

更新不易&#xff0c;麻烦多多点赞&#xff0c;欢迎你的提问&#xff0c;感谢你的转发&#xff0c; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我…

这十套练习,教你如何用Pandas做数据分析(01)

Pandas是入门Python做数据分析所必须要掌握的一个库。本文内容由和鲸社区翻译整理自Github&#xff0c;建议读者完成科赛网 从零上手Python关键代码 和 Pandas基础命令速查表 教程学习的之后&#xff0c;点击本篇Notebook右上角的 Fork 按钮对本教程代码进行调试学习。 转载本…

(附源码)SSM的KTV管理系统 毕业设计 291807

基于SSM的KTV管理系统 摘 要 随着社会的发展&#xff0c;人类的进步&#xff0c;21世纪人们的生活水平有所提高&#xff0c;为了满足人们对生活的需要&#xff0c;丰富业余生活&#xff0c;娱乐KTV等行业蓬勃发展&#xff0c;在数字化的今天&#xff0c;我们已离不开计算机&…