[C初阶]循环和分支语句

目录

if...else语句

​编辑

 易犯错误

打印100以内的奇数 

switch...case语句

输出星期

 循环语句

对比判断 

1.break终止循环

2.continue

读取字符

缓冲区读取

只输出数字字符 

 for循环

do...while循环

n的阶乘求和

 循环实现动态打印

猜数字游戏【总结】

 goto

​编辑 关机程序

 goto

while循环


if...else语句

我们先引入一个重要的概念:0为真,非0为假。

分支判断语句if...else,默认情况下都只控制一条语句,如果我们想执行多条语句可以添加大括号。{}内表示代码段。

if语句默认与最近的else相匹配。

那我们如何按照自己意愿决定if...else的匹配关系呢?答案是加上大括号:

//形式1
if (condition)
	{
		return x;
	}
	return y;
//形式2
if (condition)
	{
		return x;
	}
else
		return y;

一般推荐第二种形式代替第一种,以提高可读性。

 易犯错误
int num = 1;
if (num = 5)
{
	printf("hehe\n");
}

这段代码会陷入死循环,注意区分赋值和等于

//正确
if (num == 5)
//容易检查错误
if(5 == num)

打印100以内的奇数 

我们可以使用判断语句来输出100以内的所有奇数

	int i = 1;
	while (i <= 100)
	{
		if(i%2 == 1)
			printf("%d\n", i);
		i++;
	}
	

但我们可以凭借尝试不用判断直接利用循环语句跳过2个数也能实现这个功能:

while (i <= 100)
	{
		printf("%d\n", i);
		i+=2;
	}

switch...case语句

switch...case语句作为分支语句,意为开关。有的时候它比if...else语句更方便,可读性更高。

输出星期

正常模式:

int day = 0;
scanf("%d", &day);
if (1 == day)
	printf("星期1\n");
	else if (2 == day)
		printf("星期2\n");
	else if (3 == day)
		printf("星期3\n");
	else if (4 == day)
		printf("星期4\n");
	else if (5 == day)
		printf("星期5\n");
	else if (6 == day)
		printf("星期6\n");
	else if (7 == day)
		printf("星期天\n");

switch改写: 

当我们输入4的时候程序进入了第4个语句,成功输出了星期4但是输出了后面的分支, 你可以把它想象成电流水流,需要一个闸门控制关闭——break意为中断,类似与闸门的关闭键,遇到它就会停止。

int day = 0;
	scanf("%d", &day);
	int n = 1;
	switch (day)//整型表达式
	{
	case 1:  //case 后必须是整型常量表达式
		printf("星期1\n");
		break;
	case 2:
		printf("星期2\n");
		break;
	case 3:
		printf("星期3\n");
		break;
	case 4:
		printf("星期4\n");
		break;
	case 5:
		printf("星期5\n");
		break;
	case 6:
		printf("星期6\n");
		break;
	case 7:
		printf("星期天\n");
		break;
	}

现在我们打印休息日和工作日,可以这样修改代码:

switch (day)//整型表达式
	{
	case 1:  //case 后必须是整型常量表达式
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	default:
		printf("输入错误\n");
		break;
	}

这里就体现了switch语句的自由性,当我们输出1-7以外的数字时,我们可以使用default关键字(默认)来处理。default不一定要写在语句最后,可以为任意位置,所以我们最好在后面加上break。

 循环语句

顾名思义,循环就是满足判断条件后就会继续重复执行的操作。

对比判断 

  

当满足条件的时候他就会一直循环,我们输入一个横真条件就会进入死循环,为了灵活的控制循环,我们还添加了break和continue对循环进行控制。

1.break终止循环

遇到break循环跳出当前循环

2.continue

遇到continue忽略循环体内后面的内容,重新开始循环(跳过本次循环)

该循环到5的时候程序会进入死循环,正确做法是将i++放到循环第一句中使其不打印5。

读取字符

如果我们想从键盘中读取多个字符的话该怎么操作呢?

读取成功时返回它的整型值(对应ascii码值),这是为了适应当它读取失败时返回EOF(-1),我们也可以手动结束读取——键盘输入ctrl+z

putchar是输出字符, 成功将返回字符并输出在屏幕上,失败返回EOF。

ch通过接收getchar的返回值,对每个字符进行判断。当我们键入回车时,getchar也会读取并判断,然后通过屏幕打印出来,所以会出现单个字符占一行的效果。

缓冲区读取

 我们实现一个简单的密码确认程序来验证一下缓存区是否存在。

当我们输入密码后敲出的回车直接被ch读取,导致直接打印确认失败,这是因为scanf在遇到\n或空格后会停止输入,剩下的内容被留在了缓冲区。为了避免这种情况,我们可以用getchar将空格给读走。

添加getchar后我们的代码能成功运行

 还有一种情况需要考虑

 为什么会发生这样的事呢?

换句话说还是没有处理干净,这时候我们利用循环来清除缓冲区的内容

只输出数字字符 

int ch = 0;
while ((ch = getchar()) != EOF)//多组输入,注意优先级加括号
{
	
	if (ch < '0' || ch > '9')
		continue;
/*if(ch <= '9' && ch >= '0')*/
	putchar(ch);
}

需要注意的是,虽然用char类型也能接收getchar的返回值,但最好还是用int(可能截断)

 for循环

for循环是对while循环的一个整合,使得我们能精确地调整循环。

for(代码1;代码2;代码3)

分别代表初始条件,判断和更新

这段代码打印了除5之外的1到10的所有数字,与while循环不同的是,当更新条件放在continue后将不会执行,而for循环中使用continue能继续执行更新条件。 

for的初始化,判断,调整三个部分可以省略, 但是省略掉判断部分,就意味着判断恒为真

 如果我们省略初始部分,可能会出现这样的结果:

 不省略前打印100次,省略后由于打印10次后j的值没有被重新初始化,导致它仍然为10。

所以最好不要随便省略判断条件

do...while循环

它的特点是:至少执行一次,一般不常用。

 下面代码的结果是?

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

答案是输出1 2 3 4,同样地,由于更新条件放在continue后,执行continue后进入while循环(死循环)。

n的阶乘求和

具体思路是从1到n依次求阶乘,并依次求和。

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

注意每次循环后需要将ret变为1

第二种方法(消耗低)

n!= (n-1)! * n

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

 循环实现动态打印

给定一段字符串和同等长度的#号,使其每循环一次,左右两边进行覆盖直到#被覆盖成字符串。

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char arr1[] = "welcome to here!!!!";
char arr2[] = "###################";
int left = 0;
int right = strlen(arr1)-1;
while (left <= right)
{
	arr2[left] = arr1[left];
	arr2[right] = arr1[right];
	printf("%s\n", arr2);
	Sleep(100);//休眠命令
	system("cls");//清空屏幕命令
		left++;
		right--;
}
printf("%s\n", arr2);
}

大家可以复制这段代码到编译器中运行,可以观察到一个简单的动态效果。

猜数字游戏【总结】

我们结合本篇学的知识,用猜数字游戏做一个复习。 

编写一个建议菜单:

void menu()
{
	printf("*********************************\n");
	printf("**********  1. play  ************\n");
	printf("**********  0. exit  ************\n");
	printf("*********************************\n");
}
int main()
{
	int n = 0;
	do
	{
		menu();
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			//game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	}
while (n);
	return 0;
}

 接下来我们完善game函数 

要想实现猜数字这个功能,我们得需要电脑生成随机数,而rand是专门用来生成随机数的函数。

但rand生成的数字是伪随机,第二次运行程序的数字和第一次一模一样

所以我们用srand(随机数初始化设置器)来让随机数变成真随机。

一直在变的是时间,所以用时间函数来设置初始化。它的返回值是一个时间戳(整形)我们这里是产生随机值,所以可以传NULL来产生随机值。

 注意srand只能设置一次,所以不参与循环,我们可以把它添加到do...while循环里

	srand((unsigned int)time(NULL));

 由于time函数返回类型是time_t,而srand的参数是无符号整形,所以我们得强制转换。

void game()
{
	int num = rand()%100+1;//1-100之间
	int guess = 0;
	while (1)
	{
		printf("请猜数字:>");
		scanf("%d", &guess);

		if (guess < num)
			printf("猜小了\n");
		else if (guess > num)
			printf("猜大了\n");
		else
		{
			printf("猜对\n");
			break;
		}
	}
}

把上面的代码整合一下,我们的猜数字游戏就可以运行起来了,赶快去体验一下自己的第一个c语言小游戏吧!

 goto

作为一个跳出一层或多层循环的函数,goto语句能实现的功能都能被其他语句实现,而且它的使用可能会导致程序出现一些问题(例如跳过某些程序可能导致程序出现不可调试的bug等)。它的出场率并不高,一般出现在需要一次性跳出多个循环的场景。(break只能跳出一层循环)

 关机程序

顾名思义,就是能让电脑在特定时间关机的程序。我会用两种方式来写这个程序

 goto

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    system("shutdown -s -t 60");//60秒内关机
again:
	
	printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
	char input[20] = { 0 };
	scanf("%s", input);
	if (strcmp(input, "我是猪") == 0)
	{
		system("shutdown -a");
		printf("关机取消\n");
	}
	else
		goto again;
	return 0;
}

运行结果:

while循环

int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");

	while (1)
	{
		printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
		scanf("%s", input);
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");
			printf("关机取消\n");
			break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dwededewde/article/details/131457661