C语言---分支和循环语句

news/2024/10/18 5:52:59/

1、什么是语句

C语言语句可以分为五类:

  • 表达式语句
  • 函数调用语句
  • 控制语句
  • 复合语句
  • 空语句

C语言有九种控制语句

可以分成一下三类:

  • 条件判断语句也叫分支语句:if语句,switch语句;
  • 循环执行语句:do while语句、while语句、for语句;
  • 转向语句:break语句、goto语句、continue语句、return语句。

2、if语句

if语句的语法结构:

if (表达式)             //表达式结果如果为真或者非0,那这个表达式就会运行语句;
if (表达式)           语句;             //这里如果只有一条语句,那就不需要带{},也可以带
else语句2;if (表达式)           语句1;             //这里大于一条语句,那就需要带{}语句2;
else语句2;
//多分支
if (表达式1)           语句;            
else if(表达式2)语句2;
else语句3;//注意:如果一个表达式同时满足if语句有满足else if语句,因为if语句先接收的这个表达式,那这个表达式只会进入到if语句里面。

2.1、if是和靠的最近的else相匹配的

下面先来看段代码:

#include <stdio.h>
int main()
{int a = 0;int b = 2;if (a == 1)if (b == 2)printf("hehe\n");elseprintf("haha\n");return 0;
}

输出:

在这里插入图片描述

显而易见这里的输出竟然为空!!!

这是问什么呢?不应该是输出:haha 的结果吗?为什么不对呢?

这是因为else是会和最近的if进行匹配,所以输出为空。

在这里插入图片描述

所以说代码的结构应该是这样:

#include <stdio.h>
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是靠的最近进行匹配的,不是说else和if在同一缩进进行匹配的。

3、switch语句

switch语句也是一种分支语句

常常用于多分支的情况

比如:

输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六

语法:

switch (整型表达式)
{语句项;
}

而语句项是什么呢?

//语句项是一些case语句
//如下:
case 整形常量表达式      //case后面必须是整形常量,当然使用字母表示也行,因为字母的ASCII也是整数语句;

使用switch实现星期查询

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{	int day = 0;scanf("%d", &day);switch (day){case 1:printf("星期一\n");break;case 2:printf("星期二\n");break;case 3:printf("星期三\n");case 4:printf("星期四\n");break;case 5:printf("星期五\n");break;case 6:printf("星期六\n");break;case 7:printf("星期日\n");break;}return 0;
}

说下switch原理:

从switch中输入相对应的编号,根据编号找到相对应的case语句,这样就算进入switch语句了,然后匹配后经过break语句出switch语句。

3.1、新的需求

要求:

  • 输入1-5,输出“weekday”
  • 输入6-7,输出“weekend”
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
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;}return 0;
}

这说明case语句在没有遇到break语句之前是一下向下执行,知道遇见break语句才会跳出switch语句。

3.2、default字句

如果表达的值与所有的case标签的值都不匹配怎么办?

其实也没什么,都不匹配最终肯定是会全部跳过而已。

程序也不会终止,也不会报错,但是当在都不匹配的情况下我们最后提示一下。

那这就需要default字句了。

注意:switch语句中只能出现一个default字句

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
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("输出错误");break;}return 0;
}

输出:

在这里插入图片描述

4、循环语句

  • while
  • for
  • do while

4.1、while

语法结构

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

4.1.1、break语句

只要while循环中执行了break语句,那么整个while循环将会停止,这个break语句在while循环的那任何部分中,while都会立即终端

代码示例:

#include <stdio.h>
int main()
{int a = 1;while (a < 11){if (5 == a){break;      //这个break语句看着是在if语句中。但是一旦它被执行,那么整个while语句将会停止}printf("%d\n",a);a++;}return 0;
}

输出:

在这里插入图片描述

4.1.2、continue语句

一旦在while语句中执行了continue语句,那么此次循环将会直接跳过continue后面的代码,然后判断循环,如果继续则直接进行下一次循环(就直接从while (a<11)处开始执行)。

#include <stdio.h>
int main()
{int a = 1;while (a < 11){if (5 == a){continue;        //当a=5时,不在执行后面的代码,直接跳过从while循环开始}printf("%d\n",a);a++;}return 0;
}

输出:一直死循环的输出:1 2 3 4

在这里插入图片描述

4.2、使用while循环清理缓冲区

4.2.1、getchar()和putchar()

  • getchar()函数用于从键盘上读取数据和scanf一样
  • putchar()函数用于输出数据
#include <stdio.h>
int main()
{int ch = getchar();   //我们在键盘中输入“e”,这个e会被转为相应的ASCII值存入ch中printf("%c\n", ch);   //然后在转为字符(%c)进行输出putchar(ch);          //这个可以直接输出,和上面的打印的效果是一样的,这是另一种方法return 0;
}

输出:

在这里插入图片描述

但是这里我们有个疑问:

int ch = getchar(); 

明明getchar()接收的是个字符,为什么我们要用int类型来接收呢?为什么不用char类型接收呢?

这里解释一下:
因为在读到字符时,会转为相应的ASCII码值,所以说放在int类型是没有问题的。

重点:如果getchar()在读取过程中遇到了错误/不正常或者遇到了文件结束,那么这个函数会返回个EOF

EOF--------end of file文件结束标志

我们来看一下EOF的定义(define)

#define EOF    (-1)

可以看到EOF定义的值是-1,-1是个整数,所以说我们接收getchar()返回的数据就应该用int类型去接受

那好知道了这些我们就可以用while循环来实现清理缓冲区的功能:

#include <stdio.h>
int main()
{int ch = 0;while ((ch = getchar()) != EOF)    //这里ch接收getcha返回的数据不等于EOF,说明返回的是个正常的字符,那就可以正常输出{putchar(ch);}return 0;
}

输出:

在这里插入图片描述

会发现输出不会停止,这是Ctrl+z,然后在回车就可以终止程序了。

Ctrl+z就是让getchar返回一个EOF,这样程序就终止了

【重点:】下面来好好理解一下这个程序的逻辑:

这里先提出个问题?为什么上面的输出会自动换行?

这里设计到缓冲区的概念

我们所知道的scanfgetchar函数来从键盘上获取数据,是我们从键盘上一输出字符,scanfgetchar函数就能接收到的吗?其实并不是,正确的顺序是:我们在键盘上输出字符,这个字符会进入缓冲区,此时scanfgetchar函数检测到缓冲区有字符,这个时候scanfgetchar函数才会把该字符从缓冲区中拿出来。

那为什么会自动换行呢?

在这里插入图片描述

还是上面代码流程分析:当我们输入“a”并且回车后,(回车相当于输入了\n),首先判断a!=EOF,因此执行putchar(ch)然后打印出“a”,然后再次循环,因为缓冲区里里面“a”已经被读取了,所以还剩个“\n”,然后getchar直接读取,因为“\n”!=EOF,所以在次执行putchar(ch),所以就会自动换行了。

4.2.2、深度解析—清理缓冲区这段代码

先来看段代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);   //这里不用在&password,因为数组名就是数组首元素地址,所以不用取地址printf("请确认密码(Y/N):>");int ret = getchar();if (ret == 'Y')printf("Yes\n");else{printf("No\n");}return 0;
}

输出:

在这里插入图片描述

显然这样的输出结果是不对的,明明我还没确认,程序直接就打印了NO

分析:当我们在键盘中输入:abcdef,然后回车(\n),此时输入缓冲区里面有了:“abcdef\n”,scanf指挥取它所需要的。因此scanf把“abcdef”给拿走了,因此password=“abcdef”,但是此时缓冲区里面还有个“\n”,然后程序向下走getchar获取数据,一看缓冲区里面还有个“\n”,因此getchar直接拿走了“\n”,然后进入if判断,“\n”!=‘Y’,所以程序输出No。

在这里插入图片描述

那怎么解决呢?我们想办法只要让缓冲区里面没有字符就行了,可以这样实现:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);   getchar();     //这里在添加个getchar(),提前把那个\n读取掉,那下面那个getchar()就可以正确判断了printf("请确认密码(Y/N):>");int ret = getchar();if (ret == 'Y')printf("Yes\n");else{printf("No\n");}return 0;
}

但是这种写法是比较粗鲁的,不适用每一种情况。比如:我们在键盘中输入:abcdef sdf(中间有个空格)

在这里插入图片描述

这样又不行了。我们来分析一下为什么又出错了:

首先scanf会读取缓冲区里面的“abcdef”,也就是说scanf会读取到空格前,紧接着第一个getchar()会读取空格,那就相当于第一个getchar()被使用了,然后下面的getchar()会读取到sdf,因为’sdf’ != ‘y’,所以会输出No。

这是我们能感知到,第一个错误的解决办法是需要清理缓冲区里面的一个字符,而这个是需要清理缓冲区里面的许多个字符才能解决,因此我们需要循环解决。

我们可以循环使用getchar()把空格到“sdf”以及后面的“\n”全部读取掉,这样就行了

下面我们来实现个正确的方法:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);   int ch = 0;                          //startwhile ((ch = getchar()) != '\n'){;}                                    //endprintf("请确认密码(Y/N):>");int ret = getchar();if (ret == 'Y')printf("Yes\n");else{printf("No\n");}return 0;
}

5、for循环

5.1、语法

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

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

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

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

for循环执行顺序:

第一遍循环:

在这里插入图片描述

第2、3、4、5、6…循环:

在这里插入图片描述

5.2、break,continue

在for循环和while循环里面break语句的效果一样。

同样在for循环和while循环里面continue语句有一点小差别

如下图:

在这里插入图片描述

其中for循环在遇见continue语句后是跳过后面的代码,然后跳到“i++”(调整)中去了

二while循环在遇见continue语句后是跳到了判断里面去了。

5.3、for语句的循环控制变量

建议:

  • 不可在for循环体内修改循环变量,防止for循环失去控制。
  • 建议for语句的循环控制变量取值采用“前闭后开区间”写法。

5.4、for循环的变种

1、死循环

#include <stdio.h>
int main()
{for (;;){printf("hehe\n");}return 0;
}

__结论:__for循环的判断部分省略意味着判断或恒成立,而初始化,调整省略没事(但最好不要省略)。

2、for循环采用多个变量去控制

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

6、do-while循环

6.1、do语法

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

打印1-10:

#include <stdio.h>
int main()
{int i = 1;do{printf("%d ", i);i++;} while (i <= 10);return 0; 
}

do循环最少循环一次。

6.2、break和continue

作用一样。

7、goto语句

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

从理论上goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码

但是在某些场合下goto语句还是得用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如:一次跳出两层或多层循环。

多层循环这种情况使用break是达不到目的的,它只能从内层循环到上一层的循环。

先来看一下goto的效果:

#include <stdio.h>
int main()
{
again:                     //标签printf("hehe\n");printf("haha\n");goto again;return 0;
}//但是goto不能跨函数跳转,如下就是不行的
void test()
{again;
}int main()
{printf("hehe\n");printf("haha\n");goto again;return 0;
}

在这里插入图片描述

goto语句真正适合的场景下:

for (...){for (...){for (...){if (disaster)goto error;            #这样可以根据error标签直接跳过两层for循环}}error:if (disaster)//处理错误情况}

7.1、使用goto语句模拟关机程序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <string.h>
int main()
{char input[20] = { 0 };system("shutdown -s -t 60");             //电脑在60s内关机
again:printf("电脑即将在60秒内关机,如果不想关机,输入:我是猪,即可解决。\n");scanf("%s", input);if (strcmp(input, "我是猪") == 0){system("shutdown -a");printf("已取消关机\n");}else{goto again;}return 0;
}

输出效果:

在这里插入图片描述

当然我们也可以使用循环的方式替代goto

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <string.h>
int main()
{char input[20] = { 0 };system("shutdown -s -t 60");             //电脑在60s内关机while (1){printf("电脑即将在60秒内关机,如果不想关机,输入:我是猪,即可解决。\n");scanf("%s", input);if (strcmp(input, "我是猪") == 0){system("shutdown -a");printf("已取消关机\n");break;}}return 0;
}

http://www.ppmy.cn/news/107267.html

相关文章

AI创作工具的使用体验报告

下面是AI创作工具的使用体验报告&#xff0c;围绕以下三点展开&#xff1a; 一、工具的使用体验如何&#xff1f; CSDN博客AI创作工具是一款非常易用的工具&#xff0c;操作简单&#xff0c;可以很快地开始创建内容。在使用过程中&#xff0c;我发现它的语言模型很智能&#…

HHDESK及HHDBCS快捷升级功能

为提升用户体验&#xff0c;HHDESK及HHDBCS新增了一项功能&#xff0c;一键升级。 1 使用软件时快捷升级 在产品首页点击帮助&#xff0c;选择软件升级 弹出如下对话框&#xff1b;点击确定 随即弹出对话框&#xff1b;点击浏览&#xff0c;选择下载到本机上的新版本产品…

【移动计算技术(Android)】期末复习

目录 选择题 选择题知识点汇总 Activity Intent Broadcast BroadcastReceiver 如何自定义Receiver 如何注册接收器 Service SharedPreferences 三种访问模式 如何创建 如何存储/修改 如何读取 内部存储 openFileOutput openFileInput SD卡 资源文件 SQLite…

四足机器人A1目标跟踪

四足机器人A1目标跟踪 前期准备工作1.安装TeamViewer2.将四足机器人所有线连接好3.将四足机器人调至运动模式 运行流程1.开机阶段2.运行阶段 效果展示代码配置 前期准备工作 1.安装TeamViewer 由于外接屏幕损坏&#xff0c;故四足机器人内部配置了TeamViewer&#xff0c;因此…

使用 python 制作自动填写问卷星问卷调查程序

目录 前言环境&#xff1a;代码展示尾语 &#x1f49d; 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 你的问卷星任务还没做完吗&#xff1f;今天教你如何快速把问卷星调查任务给完成。 环境&#xff1a; anaconda5.2.0&#xff08;python3.6.8&#xff09; 编辑器: p…

生产环境之负载均衡LVS+keepalived方案(5)_关键知识点

补充知识点 arp_ignore & arp_announce https://www.cnblogs.com/lipengxiang2009/p/7451050.html 这篇博文介绍得很详细&#xff0c;以下主要做重点摘录及自己的一些总结&#xff1a; &#xff08;1&#xff09;arp_ignore理解 arp_ignore参数的作用是控制系统在收到外部…

网络面试题:什么是 TCP/IP?

目录标题 什么是 TCP/IP?1) 网络接口层:2) 网络层:3) 传输层:4) 应用层: 2.数据包3.网络接口层4.网络层1) IP:2)地址解析协议 ARP3)子网 5 传输层1&#xff09;UDP&#xff1a;2&#xff09;TCP&#xff1a; 6 应用层运行在TCP协议上的协议&#xff1a;运行在UDP协议上的协议&…

【回眸】牛客网刷刷刷!网络专项知识点大集合

前言 正文 网络设备 net_device包含的信息 DHCP作用 DHCP交互过程 DHCP饥饿攻击 注册网络设备 不具有路由功能的网络设备 Linux网络通信中sk_buff net_device结构体 查询路由表 虚拟网卡 前言 笔者是个物联网专业的应届生&#xff0c;有一天发现自己对网络相关的…