分支语句和循环语句

news2024/11/27 5:37:47

控制语句:用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有9种控制语句,可分为三类:
条件判断语句也叫分支语句:if语句,switch语句;
循环执行语句:do while语句,while语句,for语句;
转向语句:break语句,goto语句,continue语句,return语句

1.分支语句(选择语句)

if语句:

语法结构:

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

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

//如果表达式的结果为真,则语句执行
//在C语言中如何表示真假?0表示假,非0表示真

悬空else
else总是和离它最近的if进行匹配

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hehe\n");
		else
			printf("haha\n");
	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;
}
//输出:haha

案例一:

int test()
{
	int a = 2;
	if (a)
		return 1;
	return 0;
}

int main()
{
	int ret = test();
	printf("ret = %d\n",ret);//ret=1

	return 0;
}

运行结果:
在这里插入图片描述案例一改进:

int test()
{
	int a = 2;

	if (a)
		return 1;
	else
		return 0;
}

int main()
{
	int ret = test();
	printf("ret= %d\n",ret);

	return 0;
}

案例二:

int main()
{
	int num = 1;
	if (num == 5)
		printf("hehe\n");

	return 0;
}

案例二改进:

int main()
{
	int num = 1;
	//一般在写代码时候都会粗心打少一个等号,可以通过把常量放在等号左边,变量在等号右边
	if (5 == num)
		printf("hehe\n");

	return 0;
}

案例二拓展:

int main()
{
	int i = 1;
	//一个等号表示赋值即把2赋值给i并保存起来,此时语句为真
	if (i = 2)
	{
		printf("hehe\n");//打印hehe
	}
	return 0;
}

int main()
{
	int i = 1;
	//两个等号是判断i和2是否相等,1不等于2,语句为假,故不打印
	if (i == 2)
	{
		printf("hehe\n");//什么都不打印
	}
	return 0;
}

练习一:

//判断一个数是否为奇数
int main()
{
	int n = 0;
	scanf("%d",&n);

	if (1==n % 2)//(n%2!=0)
	{
		printf("奇数\n");
	}

	return 0;
}

练习二:

//输出1-100之间的奇数
int main()
{
	int n = 0;
	while (n <= 100)
	{
		if (n % 2 == 1)
		{
			printf("%d ",n);
		}
		n++;
	}
	return 0;
}

switch语句:

switch语句:常用于多分支的情况
在switch语句中case决定分支的入口,break决定分支的出口

switch (整型表达式) //表达式只能是字符型或者整型的(short int,int,long int)
{
	case 整形常量表达式:
	    语句;
}

举例说明:

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;
	}
}

运行结果:
如果改写成:

int main()
{
	int day = 0;
	scanf("%d",&day);

	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");
	}
}

运行结果:

break:我们发现上面的代码并没有实现我们想要的分支逻辑,因为当我们输入1时,输出的结果为星期一到星期天,这是因为我们没有设置分支的出口break。在switch语句中case决定分支的入口,break决定分支的出口。 break用于switch语句,表示跳出整个switch块,退出当前循环。

并不是每个case语句后面都需要加上break,可以根据需求合理使用break语句。如下所示:

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;//建议加上
	
	default:
		printf("输入错误\n");
		break;
	}
	return 0;
}

default:当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行;每个switch语句中只能出现一条default子句;但是它可以出现在语句列表的任何位置;建议将default语句放在所有case结束之后;default语句并不是必须选项,可加可不加。

练习:

int main()
{
	int n = 1;
	int m = 2;
	switch (n)
	{
	case 1:
		m++;//m=3,由于没遇到break语句,代码会继续往下执行
	case 2:
		n++;//n=2
	case 3:
		switch (n)
		{
			//switch语句允许嵌套
		case 1:
			n++;
		case 2:
			m++;//m=4
			n++;//n=3
			break;
		}
	case 4:
		m++;//m=5
		break;//跳出循环
	default:
		break;
	}
	printf("m=%d,n=%d\n",m,n);//m=5,n=3
	return 0;
}

运行结果:

2.循环语句

while循环:

while语法结构

while(表达式)
      循环语句;

案例实现:

int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d ",i);//1 2 3 4 5 6 7 8 9 10
		i++;
	}
	return 0;
}

延伸:

int main()
{
	int i = 1;
	while (i <= 10)
	{
		//break:在循环中只要遇到break,就会停止后期的所有循环,直接终止循环。所以while中的break是用于永久终止循环的
		if (5 == i)
			break;
		printf("%d ",i);
		i++;//不加这条语句就会变成死循环
	}
	return 0;
}

运行结果:break:break在while循环中的作用:在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。所以,while中的break是用于永久终止循环的。

int main()
{
	int i = 1;
	while (i <= 10)
	{
		//continue:是用于终止本次循环的,也就是本次循环中continue后面的代码不会再执行,而是直接跳转到while语句的判断部分,进入下一次循环的入口判断
		if (i == 5)
			continue;
		printf("%d ",i);
		i++;
	}
	return 0;
}

运行结果:在这里插入图片描述此时的运行结果为:1 2 3 4,并进入死循环。当i=5时,条件为真,执行continue语句,直接跳过后面语句并结束本次循环,然后进入下一次循环,i依然等于5,故会进入死循环。

int main()
{
	int i = 1;
	while (i <= 10)
	{
		i++;
		//continue:是用于终止本次循环的,也就是本次循环中continue后面的代码不会再执行,而是直接跳转到while语句的判断部分,进入下一次循环的入口判断
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	printf("\n");
	return 0;
}

运行结果:
continue:当把i++放到continue语句之前,我们得到的结果是:2 3 4 6 7 8 9 10,在输出的结果中跳过了数字5。所以continue是终止了本次的循环,也就是本次循环中continue后面的语句不再执行,而是直接跳转到while语句的判断部分,进行下一次循环的入口判断。
continue与break两个语句的区别:break是永久结束循环,而continue是终止了本次的循环,也就是本次循环中continue后面的语句不再执行。break语句刚好把程序控制转移到循环体末尾之后,而continue语句刚好把程序控制转移到循环体末尾之前。用break语句会使程序控制跳出循环,而continue语句会把程序控制留在循环内。break语句和continue语句的另外一个区别是:break语句可以用于switch语句和循环(while,do和for),而continue语句只能用于循环。

getchar函数在while循环中的应用:

getchar简介:
“函数”原型:#define getchar() getc(stdin);
getchar():在标准输入缓冲区中读取一个字符,并返回读到的字符的ASCII码值,如果读取失败,则返回EOF(-1);
getchar():读取失败时,返回EOF,EOF本质是-1(#define EOF -1),是一个整型值;而-1在char类型中,是存储不下的;再结合getchat()函数的原型,getchar()的返回类型被定义为int, 那么返回数据应该被存放在int变量中;
在调用getchar()函数时,编译器会依次读取用户键入缓冲区的一个字符(注意这里只读取一个字符,如果缓冲区有多个字符,那么将会读取上一次被读取字符的下一个字符);
如果缓存区没有用户键入的字符,那么编译器会等待用户键入并回车后再执行下一步 (注意键入后的回车键也算一个字符)

//调用举例
char c=getchar();
//等价形式
char c;
scanf("%c",&c);

注意事项:
空格,回车或者TAB键均认为是字符;
接收的一个字符在内存中存储它的ASCII码
既可以按字符形式输出,也可以按整数形式输出
输入,回车后,输入流:字符+换行符;
getchar从中获取一个字符,换行符会被残留在输入流中;
再次调用getchar或者scanf输入字符时,实际获取的是上次残留的换行符\n,无法正确获取想要的字符。
getchar解决方案:
方案一:在每次调用scanf或getchar后,再调用一次getchar用于吸收上次输入缓冲区残留的换行符;
方案二:stdio.h中的fflush函数清空输入缓冲区fflush(stdin);注意:非标准方式,可能会影响程序的可移植性。

putchar简介:
原型:#define putchar© putc(©,stdout)
功能:向终端输出一个字符
头文件:stdio.h
调用方式:
格式调用:putchar(字符常量) / putchar(字符变量)
调用举例:

char ch='a';
putchar(ch);//等价于:printf("%c",ch);
putchar('a');//等价于:printf("%c",'a');
#include<stdio.h>

int main()
{
	int ch = getchar();
	
	printf("%c\n", ch);
	putchar(ch);
	
	return 0;
}

运行结果:
getchar是如何获取我们在键盘上输入的字符的?其实getchar是从缓冲区读取字符的;在没有输入任何字符时,getchar函数会在缓冲区进行等待,当我们从键盘输入A并且按下回车时,在缓冲区中就会存有字符A和\n;这时,getchar函数就会从缓冲区读取字符A,赋值给了ch,此时缓冲区还有一个字符\n,不及时处理的话,会影响下次字符的读取。

//getchar在while循环中的作用
int main()
{
	int ch = 0;

	while ((ch = getchar()) != EOF)
		putchar(ch);

	return 0;
}

运行结果:通过运行结果分析可知,将getchar函数作为判断条件放在while循环中,就可以实现多个字符的连续输入和输出。注意:\n也是一个字符,会随着输入的字符串一并输出。最后,按Crtl+z即可停止读取,退出程序。

案列分析:

方案一:所读取的字符串中不包含空格

//方案一:所读取的字符串中不包含空格
int main()
{
	char password[20] = {0};
	//输入
	printf("请输入密码:>\n");
	//输出
	scanf("%s", password);//从缓冲区读走密码,不包含\n
	
	printf("请确认密码(Y/N):>\n");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("密码正确\n");
	}
	else
	{
		printf("密码错误\n");
	}
	return 0;
}

运行结果:
我们想要的逻辑是:当我们输入密码后,再次输入Y/N来确认密码是否正确;但是,从最后的运行结果可知,我们还没来得及输入Y或者N时,程序已自动输出:密码错误。结合前面的案例可知,当我们在键盘输入1 2 3 4 5 d f,并按下回车时,缓冲区实际存放的字符是:1 2 3 4 5 d f \n;而scanf函数在缓冲区只会读取1 2 3 4 5 d f,到\n会自动停止;当程序执行到getchar时,缓冲区剩余的字符\n会被直接读取,并存放在ch中,当执行到if语句时,判断ch不等于Y,则输出密码错误。
如何改进上面的代码呢?很显然,只要将缓冲区剩余的\n清理掉即可。

int main()
{
	char password[20] = { 0 };
	//输入
	printf("请输入密码:>\n");
	//输出
	scanf("%s", password);//从缓冲区读走密码,不包含\n

	printf("请确认密码(Y/N):>\n");

	getchar();//读取\n

	int ch = getchar();
	if (ch == 'Y')
	{
		printf("密码正确\n");
	}
	else
	{
		printf("密码错误\n");
	}
	return 0;
}

运行结果:方案二:所读取的字符串中包含空格

int main()
{
	char password[20] = { 0 };
	//输入
	printf("请输入密码:>\n");
	//输出
	scanf("%s", password);//从缓冲区读走密码,不包含\n

	printf("请确认密码(Y/N):>\n");

	getchar();//读取\n

	int ch = getchar();
	if (ch == 'Y')
	{
		printf("密码正确\n");
	}
	else
	{
		printf("密码错误\n");
	}
	return 0;
}

运行结果:方案一在输入的字符串中不包含空格时,程序是可以正常运行的,但是一旦包含空格字符时,程序就会输出“密码错误”。这是因为scanf函数在读取字符串时,遇到空格字符就会停止读取,而getchar函数一次只能读取一个字符;当第一个getchar函数读取空格字符时,第二个getchar则会读取后续的字符1,而1是不等于Y,所以会输出密码错误。
那代码又如何进行改进呢?将getchar函数放入while循环中,就可以实现缓冲区中多个字符的读取。

int main()
{
	//方案二:所读取的字符串中包含空格
	//scanf()读取字符串的时候遇到空格或者\n时就停下来不再读取了
	char password[20] = { 0 };
	printf("请输入密码:>\n");
	scanf("%s", password);

	//清理缓冲区,用来跳过输入行的剩余部分
	int tmp = 0;
	while ((tmp = getchar()) != '\n')//最后获取\n跳出循环
	{
		;//空语句,什么也不干,可以不写
	}

	//或者写成
	//while(getchar()!='\n')
	//;

	printf("请确认密码(Y/N):>\n");
	int ch = getchar();

	if ('Y' == ch)
		printf("确认成功\n");
	else
		printf("确认失败\n");
		
	return 0;

运行结果:当scanf函数从缓冲区读取字符:1 2 3 4 5后,遇到空格字符,这时scanf函数就会停止后面字符的读取;之后进入while循环,这个循环读入一个字符,把它存储在变量tmp中,然后测试变量tmp是否不是换行符。如果测试结果为真,那么执行循环体(循环体实际为空),接着再次测试循环条件,从而引发读入新的字符。最后获取字符\n并跳出循环,这时缓冲区为空,当我们再次输入Y/N就可以实现密码的确认。

//读取字符,只打印数字字符,跳过其他字符
int main()
{
	char ch = '\0';
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch>'9')
			continue;
		//putchar(ch);
		printf("%c ", ch);
	}
	return 0;
}

运行结果:

for循环:

语法格式:

for(初始化部分;条件判断部分;调整部分)
//初始化部分:用于初始化循环变量
//条件判断部分:用于判断循环什么时候终止
//调整部分:用于循环条件的调整

break在for循环中的作用:

int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (5 == i)
			break;//跳出循环,后面的循环不再执行
		printf("%d ",i);//1 2 3 4
	}
	printf("\n");

	return 0;
}

运行结果:
从运行结果可知,break在while和for循环中的作用是一样的,只要遇到break就跳出循环,不再继续执行。

continue在for循环中的作用:
案例一:

int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (5 == i)
			continue;//跳出本次循环,继续执行后面的循环
		printf("%d ", i);//1 2 3 4 6 7 8 9 10
	}
	printf("\n");

	return 0;
}

运行结果:
从运行结果可知,当i==5时,遇见continue语句,则直接结束后面语句的执行,重新跳转至for循环的判断的部分,发现5<10,则i++,并继续执行后面的语句。

案例二:

int main()
{
	int i = 0;
	for (i = 1; i <= 10;)
	{
		if (5 == i)
			continue;//跳出本次循环,继续执行后面的循环
		printf("%d ", i);//1 2 3 4
		i++;
	}
	printf("\n");

	return 0;
}

运行结果:
从运行结果可知,我们省略掉了for语句中的第三个表达式,同时为了补偿省略第三个表达式产生的后果,我们使变量i在循环体中进行自加,但是运行结果和案例一却截然不同,当输出1 2 3 4之后便陷入了死循环。这是因为执行到continue语句后,就结束了后面语句的执行,导致i不能继续自加;然后,重新跳转到for循环语句的判断部分进行判断,当i<10时,继续进入循环体,但是i==5的值却未发生变化,故会直接陷入死循环。

建议:for语句的循环控制变量的取值,采用“前闭后开”的写法

	//前闭后开写法
    for (i = 0; i < 10; i++)
    {}
	//两边都是闭区间
	for (i = 0; i <= 9; i++)
	{}

for循环的变种:
案例一:
如果省略第二个表达式,那么默认它为真值,因此for语句不会终止

	for (;;)
	{
		printf("hehe\n");//死循环
	}

案例二:
如果省略第一个表达式,那么在执行循环前没有初始化的操作

int main()
{
	int i = 0;
	int j = 0;
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			//当i=0时,j从0到9自加,当j=10时,退出循环;继续回到第一层循环,i+1=1,进入第二层循环,由于j没有初始化,此时j依旧等于10,不符合要求,则不打印
			printf("hehe\n");//打印十次
		}
	}
	return 0;
}

运行结果:
案例三:
使用多个变量控制循环

int main()
{
	//使用多个变量控制循环
	int x, y;
	for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
	{
		printf("hehe\n");//打印两次
	}
	return 0;
}

一道面试题:
案例一:

int main()
{
	//请问循环要循环多少次
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)//条件判断部分的k=0是赋值的意思,表示为假,条件不成立,故则一次也不执行
	{
		k++;
	}

	return 0;
}

运行结果:
案例二:

int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k ==0; i++, k++)//条件判断部分的k==0是等于的意思,循环一次
	{
		k++;
		printf("%d\n",k);
	}
	printf("\n");
	return 0;
}

运行结果:

do…while()循环:

do语句的特点:循环至少要执行一次,并且使用的场景有限,所以不是经常使用

语法结构:

do
{
	循环语句
}
while(表达式)

break在do…while()循环中的作用:

int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			break;

		printf("%d\n", i);
		i++;
	} while (i < 10);

	return 0;
}

运行结果:
从上面的运行结果可知,do…while循环语句中break的作用也是永久跳出循环

continue在do…while()循环中的作用:
案例一:

int main()
{
	int i = 1;
	do
	{
		if (i == 5)
			continue;

		printf("%d ", i);
		i++;

	} while (i <= 10);

	printf("\n");
	return 0;
}

运行结果:
案例二:

int main()
{
	int i = 1;
	do
	{
		i++;

		if (i == 5)
			continue;

		printf("%d ", i);
	} while (i <= 10);

	printf("\n");
	return 0;
}

运行结果:
从运行结果可知,在do…while循环语句中,continue的作用是终止本次循环,不再执行continue后面的语句。

练习:
案例一:计算n!的阶乘

int main()
{
	int n = 0;
	//输入
	scanf("%d",&n);

	//产生1-n的数字
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
	}

	printf("%d\n",ret);

	return 0;
}

运行结果:
案例二:计算1!+2!+3!+4!+5!+…+10!

int main()
{
	int n = 0;
	//输入
	scanf("%d",&n);

	int i = 0;
	int ret = 1;
	int sum = 0;

	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
		sum = sum + ret;
	}
	printf("%d\n",sum);

	return 0;
}

运行结果:
案例三:在一个有序数组中查找具体的某个数字n。(二分查找或者折半查找)
二分查找知识综述:

int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int k = 7;
	//查找k
	
	int sz = sizeof(arr)/sizeof(arr[0]);//元素个数

	int left = 0;//左下标
	int right = sz - 1;//右下标,下标是从0开始的

	while (left<=right)
	{
		int mid = (left + right) / 2;//中间元素的下标,或者:int mid=left+(right-left)/2;

		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是:%d\n", mid);
			break;
		}
	}

	if (left > right)
		printf("找不到了\n");

	return 0;
}

运行结果:
案例四:编写代码,演示多个字符从两端移动,向中间汇聚

int main()
{
	char arr1[] = "welcome to CSDN!!!!!";
	char arr2[] = "####################";

	//char arr[]="abc";
	//[a b c \0]
	//sizeof(arr1)/sizeof(arr1[0]);//4
	int left = 0;
	int right = sizeof(arr1) / sizeof(arr1[0]) - 2;//减2的原因是字符串中包含一个\0
	//int right=strlen(arr1)-1;//strlen计算长度时不包含\0

	while (left<=right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);//单位是毫秒
		system("cls");//清理屏幕
		left++;
		right--;
	}
	printf("%s\n",arr2);
	return 0;
}

运行结果:
案例五:编写代码实现,模拟用户登录情景,并且只能登录三次(只允许输入三次密码,如果密码正确则提示登陆成功,如果三次均输入错误,则退出程序)

int main()
{
	int i = 0;
	char password[20] = {0};
	//假设正确的密码是“abcdef”

	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:>\n");
		scanf("%s",password);
		if (strcmp(password, "abcdef")==0)
		{
			printf("密码正确\n");
			break;
		}
		else
		{
			printf("密码错误,重新输入!\n");
		}
	}

	if (i == 3)
	{
		printf("三次密码均输入错误,退出程序\n");
	}
	return 0;
}

运行结果:

案例六:猜数字游戏
需求
1.电脑随机生成一个数(1-100);
2.玩家猜数字:玩家猜小了,就告知猜小了;玩家猜大了,就告知猜大了,直到猜对为止;
3.游戏可以一直玩
在这里插入图片描述

//菜单选项
void menu()
{
	printf("********************\n");
	printf("*******1.play*******\n");
	printf("*******0.exit*******\n");
	printf("********************\n");
}


//猜数字游戏的实现
//时间戳:用以生成一个随机数,获取的是程序在运行时的那一刻的电脑上的时间
//c语言提供了一个函数time,返回时间戳
//time函数:用以获取系统时间,返回的是个整数
void game()
{
	int guess = 0;

	//1.生成一个随机数
	//rand函数用于生成一个随机数,返回的随机数的范围是0-RAND_MAX,也就是(0-32767),这个函数生成的随机数是int型的整数;但是在测试的时候发现,程序不管运行多少次,都会生成相同的随机数,为了解决这个问题必须使用srand函数。
	//srand函数:设置用于生成随机数的种子。rand函数是对一个叫作“种子”的基准值加以运算来生成随机数的。之所以先前每次运行程序都会生成同一个随机数序列,是因为rand函数的默认种子是常量1。要生成不同的随机数,就必须改变种子的值。而srand函数就是负责这个任务的。
	//一旦决定了种子的值,之后生成的随机数序列也就确定了,因此,如果想要每次运行程序时都能生成不同的随机数序列,就必须把种子值本身从常量编程随机数。
	//rand函数生成的是叫作伪随机数的随机数。伪随机数看起来像随机数,却是基于某种规律生成的。而真正的随机数是无法预测接下来会生成什么数值的。
	//我们一般使用的方法是把运行程序时的时间当作种子
	//一般情况下,我们需要的是某个特定范围内的随机数,这时候就用到取模运算。
	
	int ret = rand()%100+1;//取模,实现1-100之间的数据
	//printf("%d\n",ret);

	//2.猜数字	
	//并不是猜一次就能成功,所以需要猜好几次,所以需要用循环来实现
	while (1)
	{
		printf("猜数字:>\n");
		scanf("%d", &guess);

		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}


int main()
{
	int input = 0;
	
	srand((unsigned int)time(NULL));//srand要传进去一个一直在变化的值,并将其强制转化成无符号的int类型
	//srand函数不需要频繁地调用,整个工程只需要调用一次

	do
	{
		menu();
		printf("请选择;>");
		scanf("%d",&input);

		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
		
	} while (input);
	
	return 0;
}

运行结果:

goto语句:

break语句和continue语句都是跳转语句:它们把控制从程序中的一个位置转移到另一个位置。这两者都是受限的:break语句的目标是包含该语句的循环结束之后的那一点,而continue语句的目标是循环结束之前的那一点,goto语句则可以跳转函数中任何有标号的语句处;
goto语句可以随意滥用,其实实践中,没有必要;
goto语句不能跨函数跳转;
goto语句最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。例如:一次跳出两层或多层循环。多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环;

int main()
{
	int i = 0;
	int j = 0;
	int k = 0;
	for (i = 1; i <= 10;i++)
	{
		for (j = 1; j <= 10; j++)
		{
			for (k = 1; k <= 10; k++)
			{
				k = i + j;
				goto end;//此时可以直接结束所有的for循环,直接跳到第二个end后面printf("%d",k)的语句并打印k的值
			}
		}
	}
end:
	printf("%d\n", k);
	return 0;
}

运行结果:
关机程序:

//只要程序运行起来,电脑就在1分钟内关机,如果输入:我是猪,就取消关机
int main()
{
	char input[20] = {0};

	system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的
again:
	printf("请注意你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");

	scanf("%s",input);

	//判断
	if (strcmp(input, "我是猪") == 0)
	{
		system("shutdown -a");//取消关机
	}
	else
	{
		goto again;
	}

	return 0;
}

改造成不带goto的循环语句:

int main()
{
	char input[20] = { 0 };

	system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的

	while (1)
	{
		printf("请注意你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");

		scanf("%s", input);

		//判断
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");//取消关机
			break;
		}
	}

	return 0;
}

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

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

相关文章

【基础算法】贪心算法基础

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招算法的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于代码随想录进行的&#xff0c;每个算法代码参考leetcode高赞回答和…

对SRC逻辑漏洞挖掘的思考

对SRC逻辑漏洞挖掘的思考 1.限制购买逻辑漏洞一人一单限制差价活动购买限制 2.支付类逻辑漏洞3.接口未授权逻辑漏洞4.越权类逻辑漏洞5.修改返回包进入后台6.任意用户注册7.重置任意用户 1.限制购买逻辑漏洞 一人一单限制 很多厂商都会搞一些活动&#xff0c;在享受优惠的时候…

微服务架构及工作原理!

在移动计算时代&#xff0c;应用程序开发人员应该能够快速部署操作并进行更改&#xff0c;而无需重新部署整个应用程序。结果&#xff0c;它导致了一种称为“微服务”的构建软件的新方法。 微服务是应用程序中独立的小部分&#xff0c;每个部分都完成自己的工作并通过API相互通…

Dubbo学习笔记

目录 简介 Dubbo高可用 集群容错 服务治理 Dubbo线程IO模型 源码层面 Java SPI 的问题 源码解析 简介 Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架&#xff0c;可以和Spring框架无缝集成。 Dubbo提供了…

主流总线通信和系统接口技术

一、关于现场控制总线 现场总线是自动控制领域的计算机局域网&#xff0c;应用在生产现场&#xff0c;在微机测控设备之间实现双向、串行、多节点数字通信&#xff0c;是一种开放式、数字化、多点通信的底层控制网络。 现场总线具有较高的测控能力指数 得益于仪表的微机化&am…

C++实现闭散列/开放定址法

前言 哈希冲突是无法避免的&#xff0c;只能尽可能的减少冲突的可能性&#xff0c;通常我们可以设计适合的哈希函数。但是&#xff0c;哈希冲突还是会发生&#xff0c;那我们如何解决呢&#xff1f; 我们可以使用闭散列/开放定址法的方法&#xff0c;解决哈希冲突 文章目录 前…

世界超高清大会发布重大技术成果:博冠自主创新推动8K摄像机攻关

一、世界超高清大会背景介绍&#xff1a; 近日&#xff0c;由工业和信息化部、国家广播电视总局、中央广播电视总台、广东省人民政府主办的2023世界超高清视频产业发展大会在广州越秀国际会议展览中心盛大召开。自2018年创办以来&#xff0c;大会已成功举办四届&#xff0c;成…

第08讲:搭建 SkyWalking 源码环境,开启征途

搭建 SkyWalking 源码环境 下载 SkyWalking 源码 执行 git clone 命令从 GitHub下载 SkyWalking 源码&#xff0c;如下所示 &#xff1a; git clone gitgithub.com:apache/skywalking.git 切换分支 等待 clone 完成之后&#xff0c;我们通过命令行窗口进入 SkyWalking 源码根…

SSM 三大框架原理、核心技术,运行流程讲解

作者:arrows 来源:https://www.cnblogs.com/arrows/p/10537733.html 一、Spring部分 1、 Spring的运行流程 第一步&#xff1a;加载配置文件ApplicationContext ac new ClassPathXmlApplicationContext(“beans.xml”); &#xff0c;ApplicationContext接口&#xff0c;它由…

存储卡目录变成未知文件?这些技巧能让你恢复数据!

当存储卡的目录变成未知文件时&#xff0c;我们无法直接访问存储卡中的数据。但是&#xff0c;这并不意味着这些数据永远无法恢复。以下是几种可能恢复存储卡数据的方法&#xff1a; 使用数据恢复软件。从互联网上下载并安装专业的数据恢复软件这些软件可以扫描存储卡&#xf…

分布式接口幂等性设计实现

面对分布式架构和微服务复杂的系统架构和网络超时服务器异常等带来的系统稳定性问题&#xff0c;分布式接口的幂等性设计显得尤为重要。本文简要介绍了几种分布式接口幂等性设计实现&#xff0c;包括Token去重机制、乐观锁机制、数据库主键和状态机实现等&#xff0c;以加深理解…

面板安全增强,网站支持反向代理设置,1Panel开源面板v1.2.0发布

2023年5月15日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.2.0版本。 在这一版本中&#xff0c;1Panel着重增强了安全方面的功能&#xff0c;包括安全入口访问、面板SSL设置、网站密码访问等&#xff0c;同时网站新增支持反向代理设置&#xff0c;并带…

JVM学习(三)

1. JAVA 四中引用类型 1.1. 强引用 在 Java 中最常见的就是强引用&#xff0c; 把一个对象赋给一个引用变量&#xff0c;这个引用变量就是一个强引 用。当一个对象被强引用变量引用时 &#xff0c;它处于可达状态&#xff0c;它是不可能被垃圾回收机制回收的&#xff0c;即…

Java阶段二Day21

Java阶段二Day21 文章目录 Java阶段二Day21整合Lombok基础组件1 Lombok简介2 安装和配置 Lombok3 Lombok 注解及其用法3.1 Getter 和 Setter3.2 ToString3.3 AllArgsConstructor 和 NoArgsConstructor3.4 Data 4. 总结5 微博项目优化 Knife4j1 Knife4j的优点2 Knife4j快速上手2…

使用Docker构建的MySQL主从架构:高可用性数据库解决方案

前言 MySQL主从架构&#xff0c;我们已经在vmware虚拟机上实践过了&#xff0c;接下来我们一起探讨在docker中如何使用MySQL主从架构。 &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;阿里云社…

《论文阅读》基于提示的知识生成解决对话情感推理难题

《论文阅读》基于提示的知识生成解决对话情感推理难题 前言摘要作者新观点问题定义模型框架Global ModelLocal ModelPrompt Based Knowledge Generation分类器实验结果问题前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后感到失…

openEuler 成功适配 LeapFive InFive Poros 开发板

近日&#xff0c;openEuler RISC-V 23.03 创新版本在跃昉科技的 Poros 开发板上成功运行。 openEuler 在 Poros 上适配成功&#xff0c;XFCE 桌面启动正常&#xff0c;文件系统、终端模拟器和输入法等相关 GUI 应用也运行流畅&#xff0c;Chromium 浏览器和 LibreOffice 等应用…

【Pm4py第三讲】关于Output

本节用于介绍pm4py中的输出函数&#xff0c;包括日志输出、模型输出、面向对象日志输出等。 1.函数概述 本次主要介绍Pm4py中一些常见的输入函数&#xff0c;总览如下表&#xff1a; 函数名说明write_bpmn()用于写入bpmn模型write_dfg()用于写入dfg模型write_pnml() 用于写入p…

面试之高手回答

1.int与Integer的区别 int与Integer的区别有很多&#xff0c;我简单罗列三个方面 第一个作为成员变量来说Integer的初始值是null&#xff0c;int的初始值是0&#xff1b; 第二个Integer存储在堆内存&#xff0c;int类型是在直接存储在栈空间&#xff1b; 第三个integer是个对象…

项目管理6大避坑技巧

1、拒绝错位战略目标 明确目标方向 做项目&#xff0c;首先需要明确项目目标。项目中有很多目标都很重要&#xff0c;但只有一两个目标是最重要的。在任何时刻&#xff0c;我们主要精力都应该集中在一到两个最重要的目标上。 一般最重要的目标具有以下特点&#xff1a;能够给组…