C语言基础2:分支语句和循环语句(if、else、switch、while、for、goto、EOF、猜数字、关机小程序)

C语言基础2:分支语句和循环语句

1.C语言语句概述

  C语言是一门结构化的程序设计语言,可将语言分为三大结构:
①顺序结构
②选择结构
③循环结构
在这里插入图片描述
C语言的语句有很多,有①表达式语句②函数调用语句③控制语句④复合语句⑤空语句

这里主要讲控制语句,控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:
(1)条件判断语句也叫分支语句:if语句、switch语句;
(2)循环执行语句:do while语句、while语句、for语句;
(3)转向语句:break语句、goto语句、continue语句、return语句。

2.分支语句

  这里举例一下:①高考成绩高→考上大学②高考成绩不高→没考上大学
在这里插入图片描述

2. 1 if 语句

  两种 if 语句的表达式

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

  if 语句可以单独使用,如果不满足则不执行。

①
  这里的 if 语句条件是(18 <= age < 28),之所以可以打印结果为“未成年”,是因为age < 18满足条件。
在这里插入图片描述

2.1.2 if的 if else 语句

  如果 if 后的表达式成立,则执行相应的语句,否则执行 else 语句。
在这里插入图片描述
  在C语言中,0表示假,非0表示真 ,如果要多条语句成立,应该使用代码块 {} 将代码框出来这里的一堆 {} 就是一个代码块。否则,就会出现如下错误。
在这里插入图片描述
  我们加上 {} ,程序就运行正常了。
在这里插入图片描述

2.1.3 if的 else if 语句

  else if 语句,如果 if 不成立 ,则执行后面的else if 语句,直到表达式匹配,或者到执行 else 语句。
在这里插入图片描述
在这里插入图片描述

2.1.4 悬空else语句

  else 的匹配机制:else 和它最近的 if 匹配。而不是对齐的 if 进行匹配。
在这里插入图片描述
  要想 else 不和最近的 if 匹配,还是按规范加上 {}
在这里插入图片描述

2.1.5 if 书写形式的对比

在这里插入图片描述
  在写 if 的判断表达式的时候,如果 == 写成了 = 就变成了赋值运算,那么表达式 大于0,为真,就会执行相应的语句,建议 5 == a的书写方式
在这里插入图片描述

2. 2 switch 语句

2.2.1 switch 语句中的 break

  switch语句也是一种分支语句,常常用于多分支的情况。下面的程序中,当我们输入2的时候,switch 语句匹配到 case 2,然后输出星期2,并 执行 break 跳出循环结构
在这里插入图片描述
  如果我们删除 break,然后输入 2 ,在运行的时候,就会发现输出 “星期2星期3星期4” ,说明程序从上由下一次执行,而没有跳出循环结构体。
在这里插入图片描述
  通过这种方式,我们可以在输入 “1、2、3” 的时候,都可以打出 “工作日” 三个字,减少代码的量。
在这里插入图片描述
  除此之外,还需要注意,day、case后的数字类型必须是整形,如果我们定义的时候,直接定义成 单精度类型,那么程序就会发生报错。
在这里插入图片描述
  当我们把case 后的数字写成浮点数的时候,警告处就会有提示,此常量表达式为double,而所需类型为 int 。
在这里插入图片描述
  也可以写成算数:例如 case 1+3,但也必须是整形。

在这里插入图片描述
   case 的表达式必须为常量,不可以设置为变量,如果设置为变量后,程序就会出错。
在这里插入图片描述

2.2.2 default 语句

  表达的值与所有的case标签的值都不匹配怎么办,结构就是所有的语句都被跳过,程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。

default:可以写在任何一个 case 标签可以出现的位置。

  当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
在这里插入图片描述

2.2.3 switch 允许被嵌套:
#define _CRT_SECURE_NO_WARNINGS 1
#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;
}

  最后的计算结果为 m = 5 , n = 3 。
在这里插入图片描述

3.循环语句

  只要满足表达式,则执行相应的语句,下面的举例中,1 为真。 就会执行对应的语句,执行while 循环的时候,由于 1 恒为真,所以会陷入 死循环。
在这里插入图片描述

3.1 while 循环

  while 语句的执行流程如下图,表达式成立,执行语句(statement ),如果不成立,则跳出循环体,遇到 continue 则跳出本轮循环,执行下一轮循环。遇到 break 则跳出循环体。
在这里插入图片描述

3.1.1 while 语句中的 break 和 continue

  这是一个正常的循环,打印1~10个数字在屏幕上。
在这里插入图片描述
  加上判读语句当 i 等于3 的时候,则跳出本轮循环,进行 i 为 4 时的循环,而当 i 等于8的时候,则跳出循环体,终止循环,后续的 i = 9 和 i = 10的时候都不会遇到了。
在这里插入图片描述

3.1.2 while 循环中break 和 continue的总结

总结:
(1)break在while循环中的作用:
在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。while中的break是用于永久终止循环的。

(2)continue在while循环中的作用就是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,
而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。

在这里插入图片描述

3.1.3 EOF 文件结束标志符

EOF:end of file 文件结束标志,相当于-1。设置一个程序,可以获取到输入的字符串,之后并打印输入的字符串。
在这里插入图片描述
  EOF 详细解释,通过右键转到定义,分析EOF的详细解释。
在这里插入图片描述
  定义中,我们可以看到关于EOF的定义为 -1 。
在这里插入图片描述

  关于EOF 如何使用,先用下面一个程序说明,这个程序模拟用户输入密码,输入密码后按Y进行确认。然后我们Ctrl+F5(Fn),运行程序,之后按Ctrl+F10(Fn)调试,调出监视窗口。
在这里插入图片描述
  当程序运行到这里的时候,就可以看到 password和 ret 的值,password 的值为123456,而 ret 的值为10
在这里插入图片描述
  ASCII码中10其实就是 ‘\n’ ,可以用printf("%d", ‘\n');打出来测试,说明 我们输入123456后,按的Entergetchar() 捕获了,然后赋值给了 ret 。而 10Y,所以输出确认失败。

  scanf 和 getchar() 都是输入函数,具体是怎么抓取用户输入的数据呢,首先是有一个输入缓冲区,就是我们光标不停闪烁等待我们进行输入的窗口。我们实际输入的是 123456 \n ,那么此时的输入缓冲区的内容是123456 \nscanf 读到的内容只能是123456,此时的缓冲区只剩下\n,到 getchar() 读内容的时候,只能读到 \n 了,那么就把值赋给了 ret ,最终导致输出结果没有达到预期。
在这里插入图片描述
  那么,如何达到我们的预期效果呢,首先scanf 从缓冲区读取了123456,当getchar 读取缓冲区
在这里插入图片描述
但是当我们输入有空格的密码的时候,就会出现下面这样的报错:
在这里插入图片描述
  当出现空格的时候,scanf 会把空格前的字符读走,也就是上面的12345,此时缓冲区剩余 空格abcd,之后到getchar()运行了,getchar()会读出空格,而当ret = getchar();运行的时候,缓冲区里还有abcd,那么只会读出一个a

解决这个问题,我们自然需要getchar() 把所有剩余缓冲区的字符全部读完,我们可以加上条件,让getchar()读到最后一个字符 ‘\n’ ,或者换成EOF如开始示例一样。
在这里插入图片描述
打印 从字符0到字符9之间的数字字符,并输出。
在这里插入图片描述
在这里插入图片描述

3.2 for 循环

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

表达式1:为初始化部分,用于初始化循环变量的。
表达式2:为条件判断部分,用于判断循环时候终止。
表达式3:为调整部分,用于循环条件的调整
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  continue 和 break 的使用,区别,之前有提到过。
在这里插入图片描述
注意事项:
①不可在for 循环体内修改循环变量,防止 for 循环失去控制。
②建议for语句的循环控制变量的取值采用“前闭后开区间”写法。

int i = 0;
//前闭后开的写法
for(i=0; i<10; i++)
{}
//两边都是闭区间
for(i=0; i<=9; i++)
{}
3.2.2 for 循环的变种

   for循环中的初始化部分,判断部分,调整部分都是可以省略的,判断部分省略则判断条件就是恒为真。省略时应该考虑导致的问题。
在这里插入图片描述
在这里插入图片描述
  但是在省略条件时,需要注意,避免出问题。
在这里插入图片描述
原因:当 i = 0 ,j = 3 的时候,j 的 for 循环条件将不再满足,会进行 i = 1时的循环,而此时由于 j = 3 没有被赋值为 j = 0j 依然等于3那么循环条件不满足,循环结束。
在这里插入图片描述

#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 //判断条件k=0,0赋值给k,说明k为假,判断条件不满足,所以循环不执行。
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0;
}

3.3 do while 循环

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

在这里插入图片描述
  使用 do while 循环打印1-9。
在这里插入图片描述

3.3.2 猜数字实验

  生成随机数1-100,然后用户进行猜测,猜大了会返回猜大了,猜小了会返回猜小了,知道猜对为止。

3.3.2.1.1 创建随机数

(1)在创建随机数的时候,这里使用rand函数来创建随机数,但使用的过程需要注意到一些问题。首先打开MSDN,索引处输入关键字 RAND ,看一下RAND函数如何使用

  看到RAND函数调用时注释有说明:使用 srand 函数去设置一个随机数的生成器在调用 rand 之前,下面画线的区域有介绍。
在这里插入图片描述

(2)然后点开 srand 打开看到简介:设置一个随机器生成器
在这里插入图片描述
  下面有个举例,我们可以看到,srand 函数的用法中调用了time函数,通过这个例子,我们就知道随机数是通过动态的时间被srand引用,进而使rand函数生成相应的随机数。

  生成随机数 srand((unsigned)time(NULL));
在这里插入图片描述
  如果我们不使用 time 函数,在srand函数中写1、2等非随机数字,我们可以看到,他其实也不是随机的。所以需要用 time 函数,让srand函数中的值不断变化,进而生成随机数。
在这里插入图片描述
在这里插入图片描述

(3)time
  srand 再看看time 函数内不同的数字能够得到不同的结果,为了解决不够随机的问题,我们可以使用时间戳来设置随机数的生成起点,时间戳 = 当前计算机的时间 - 计算机的起始时间(1970.1.1.0:0:0) = xxxxxx秒
在这里插入图片描述
  time_t本质上是一个长整形,下面是把函数转到定义的截图
在这里插入图片描述
在这里插入图片描述

3.3.2.1.2 猜数字实验
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
//生成随机数1-100,用户进行猜测,猜大了会返回猜大了,猜小了会返回猜小了,直到猜对为止
void menu()
{
	printf("**********************************\n");
	printf("*****     1.play    0.exit   *****\n");
	printf("**********************************\n");
}

void game()
{
	int ret = 0;
	int guess = 0;
	ret = rand()%100 + 1;
	printf("%d\n", ret);
	printf("请输入猜测的数字(1-100):");
	while (1)
	{
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜您,猜对了\n");
			break;
		}
	}
}

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入 1 或 0 来决定是否游玩:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			break;
		default:
			printf("选择错误,请重新输入");
			break;
		}

	} while (input);
	return 0;
}
3.3.3 goto 语句
3.3.3.1 goto 语句

  goto 语句是C语言中提供了可以随意使用的 goto语句和标记跳转的标号。

  从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过
程。

例如:对于一次跳出两层或多层循环这种情况使用break是达不到目的的,它只能从最内层循环退出到上一层的循环。
在这里插入图片描述
  goto 语言真正适合的场景如下:使用过程中,可以跳出多层循环

for(...)
    for(...)
   {
        for(...)
       {
            if(disaster)
                goto error;
       }
   }
    …
error:
 if(disaster)
         // 处理错误情况
3.3.3.2 关机小程序:

  写一个关机小程序,可以实现让电脑在60s内关机,如果不想关机,需要输入“不要关机”来阻止电脑继续关机,如果输入的是不是“不要关机”那么需要重新输入。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	char input[10] = { 0 };
	system("shutdown -s -t 60");
again:
	printf("电脑在60s内关机,如不想关机请输入“不要关机”\n");
	scanf("%s", &input);
	if (strcmp(input, "不要关机") == 0)
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  如果想要该程序自动运行,可以把启动类型改为手动,然后将可执行程序放在开始菜单的启动栏。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值