C语言深度解析--分支语句和循环语句

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

分支语句(选择语句)

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

运行结果:

循环语句

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值