【C语言】分支与循环语句

什么是语句?

C语句可分为以下五类:

  1. 表达式语句
  2. 函数调用语句
  3. 控制语句 (本篇重点介绍)
  4. 复合语句
  5. 空语句

控制语句用于控制程序的执行流程,以实现程序的各种结构方式。C语言支持三种结构:

  • 顺序结构
  • 选择结构
  • 循环结构

它们由特定的语句定义符组成,C语言有九种控制语句。可分成以下三类:

  1. 条件判断语句(分支语句):if语句、switch语句;
  2. 循环执行语句:do while语句、while语句、for语句;
  3. 转向语句:break语句、goto语句、continue语句、return语句。

分支语句(选择结构)

if语句的语法结构可以分为单分支结构,双分支结构和多分支结构。

   单分支                    双分支                       多分支if(判断表达式)           if(判断表达式)                  if(判断表达式1)
{                       {                             {语句列表;                语句列表1;                   语句列表1}                       }                             }else                          else if(判断表达式2){                             {语句列表2;                   语句列表2}                             }else{语句列表3}  
这里的一对{}称为一个代码块,建议无论语句列表是一句代码还是多句,都带上{}

如果表达式的结果为真,则语句执行。在C语言中,0表示假,非0表示真。实例如下:

  1. 在单分支结构中:若判断表达式结果为真,则执行if中的语句;若判断表达式的结果为假,不执行if中的语句,按照源程序的顺序接着执行。
    在这里插入图片描述
  2. 双分支结构中:若判断表达式结果为真,则执行if后大括号内部的语句1;若判断表达式的结果为假,执行else中的语句2。
    在这里插入图片描述
  3. 多分支结构中:若判断表达式1的结果为真,则执行if后大括号内部的语句1;若判断表达式1的结果为假,则进入判断表达式2,若结果为真,执行语句2,若结果为假,执行else中的语句3;再次说明,多分支的分支个数并不止图例中3个,可能更多,请根据实际情况进行操作。

    在这里再对多分支语句进行强调,也是非常重要的一点,无论大家在使用多分支时在 if 和 else 中间使用多少 else if , 它归咎到底还是一条语句,只会进入符合条件的那一个选项中。其次不建议大家将 else if 写为 if (根据题目要求进行理性选择),虽然效果相同,但是在程序真正执行时 if–else if–else语句最少判断一次,最多判断(假设有3个else if)4次,而使用 if 替代 else if 后,无论判断表达式为真或为假,它都要进去判断一次,及判断次数永远包含所有情况,判断效率大大下降,希望大家能够理解。

悬空else

else 与离它最近的 if 匹配。

适当地使用{}可以使代码的逻辑更清楚,避免一些阅读程序的误会。

代码风格非常重要,好的代码风格不但可以让阅读代码的读者清晰的理解,而且可以使自己的思维逻辑更加清晰不容易出错,推荐书籍《高质量的C/C++编程》。

简单举两个例子(两个例子中的代码1和代码2输出结果均相同):
在这里插入图片描述
在这里插入图片描述

if书写形式的对比

用{}使代码误读率下降。

    代码1                               代码2if(判断表达式)                      if(判断表达式)
{                                  {return x;                          return x;
}  
else                               }
{return y;                      return y;
}
//推荐                             //不推荐

在比较变量和常量是否相等时,写为 常量==变量 的形式,可以有效避免一些代码问题。

   代码1                                  代码2int num = 1 ;                          int num = 1;
if(5 == num)                           if(num == 5)
{                                      {printf("JX\n");                        printf("JX\n");    
}                                      }
//推荐                                 //不推荐

switch语句

switch语句也是一种分支语句。常常用于多分支的情况。

switch的构造如下:

switch 在圆括号中的表达式值是一个整数值(包括char类型),case 标签必须是整数类型(包括char类型)的常量或整形常量表达式,不可以用变量来作为 case 的标签。

switch(整形表达式)                        
{case 常量1:语句;case 常量2:语句;default:语句;
}

switch语句中的 break

在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。

#include <stdio.h>                         #include<stdio.h>
int main()                                 int main()
{                                          {int day = 0;                               int day = 0;    scanf("%d",&day);                          scanf("%d",&day);switch(day)                                switch(day)       {                                          {case 1case 1:printf("星期一\n");                    case 2:      break;                                 case 3:case 2:                                    case 4:printf("星期二\n");                    case 5:break;                                     printf("周内\n");case 3:                                        break;printf("星期三\n");                    case 6:break;                                 case 7:case 4:                                        printf("周末\n");printf("星期四\n");                         break;break;                                 default:                           case 5:                                        printf("输入错误\n");printf("星期五\n");                        break;break;                                 }                 case 6:                                    return 0;          printf("星期六\n");                }      break;case 7:printf("星期天\n");break;                              好习惯:default:                       < —————— 在 switch 语句中都放一条default子句,printf("选择错误\n");              可以在后面加一个breakbreak;}return 0;
}

break语句实际效果是把语句列表划分为不同的分支部分。break 语句是 switch 语句的出口,让程序离开 switch 语句,跳转到其下一条语句,如果没有 break 语句,就会从匹配标签的第一个case开始一直执行到 switch 末尾。

顺便总结一下,break 语句既可以用于循环语句中同时也可以用于 switch 语句中,但 continue 只能用于循环中。如果 switch 语句在一个循环中,continue 就可以作为 switch 语句的一部分,就像在其他循环一样,continue 让程序跳出循环的剩余部分,包括 switch 语句的其他部分。

default子句

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

其实也没什么,结构就是所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中增加一条default子句,把标签 default: 写在任何一个 case 标签可以出现的位置。当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
好习惯:在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。

阅读代码,提升理解

#include <stdio.h>                        //switch允许嵌套使用
int main()
{int n = 1;int m = 2;switch (n){case 1:m++;case 2:n++;case 3:switch (n){                 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,你答对了吗?

循环语句

while 循环

while的语法结构:         while(判断表达式){循环语句;}             

具体实现为,如果判断表达式为真,执行循环语句一次,然后返回判断表达式再次判断;在判断表达式为假之前,循环的判断和执行一直重复进行,每一次循环都被称为一次迭代。图解如下:
在这里插入图片描述
了解了while的工作流程,就来实现一下在屏幕打印1~10的数字。
在这里插入图片描述

while语句中的break和continue

break介绍

在这里插入图片描述

break在while循环中的作用:

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

continue介绍

在这里插入图片描述

continue在while循环中的作用就是:

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

getchar() 和 putchar()

对于scanf和getchar这样的输入函数,它们若想得到输入的内容,是这样进行的:你先在键盘上将所输入的东西打到缓冲区中,然后再将缓冲区中的内容传递给了输入函数。也就是说还有一个缓冲区。
在这里插入图片描述
由于 getchar() 和 putchar() 这两个函数只处理字符,所以它们比通用的 scanf() 和 printf() 函数更快、更简洁。并且这两个函数不需要转换说明,因为它们只处理字符。它们定义在 stdio.h 头文件中,比较特殊的是,getchar() 和 putchar() 通常是预处理宏,不是真正的函数。

在这里插入图片描述

  1. scanf()函数默认是读取到空白字符停止或在结尾处停止(其中键盘敲击的\n不会被读取)。
  2. getchar() 和 putchar() 一次只读取一个字符(又像是逐字符进行读取),并且将其转化为 int 类型(对应ASCLL码值)赋给ch。

在这里插入图片描述
在这里插入图片描述

for循环

语法

for(表达式1(变量初始化); 表达式2(判断表达式); 表达式3(调整变量))
{循环语句;
}
  • 表达式1为初始化部分,用于初始化循环变量的。
  • 表达式2为条件判断部分,用于判断循环时候终止。
  • 表达式3为调整部分,用于循环条件的调整。
    在这里插入图片描述
    在while循环中也存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。

for循环中的break和continue

我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。但是结果就不一样了。在这里插入图片描述
在这里插入图片描述

for语句的循环控制变量

建议:

  1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
  2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
int i = 0;
//前闭后开的写法
for(i=0; i<10; i++)
{...}
//两边都是闭区间
for(i=0; i<=9; i++)
{...}

一些for循环的变种

for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

do…while()循环

do语句的语法

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

do语句的特点

循环至少执行一次,但使用的场景有限,所以不是经常使用。

在这里插入图片描述

do while 循环中的break和continue

跟前面的while和for几乎是一样的,直接上例子。

在这里插入图片描述
在这里插入图片描述

goto语句

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

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

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

goto语言真正适合的场景如下:

for(...)
{for(...){for(...){if(disaster)goto error;}....}
}
error:
if(disaster)
{// 处理错误情况
}

下面是使用goto语句的一个关机程序,然后再使用循环的实现方式替换goto语句:

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

而如果不适用goto语句,则可以使用循环:

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaScript】new原理解析

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

汇编语言指令系列

目录 &#xff08;一&#xff09;七大寻址方式 ① 立即寻址&#xff1a; ② 寄存器寻址&#xff1a; ③ 直接寻址&#xff1a; ④ 寄存器间接寻址&#xff1a; ⑤ 变指寻址&#xff1a; ⑥ 相对寻址&#xff1a; ⑦ 位寻址&#xff1a; &#xff08;二&#xff09;重要…

分类模型评估方法

1.数据集划分 1.1 为什么要划分数据集? 思考&#xff1a;我们有以下场景&#xff1a; 将所有的数据都作为训练数据&#xff0c;训练出一个模型直接上线预测 每当得到一个新的数据&#xff0c;则计算新数据到训练数据的距离&#xff0c;预测得到新数据的类别 存在问题&…

冒泡排序--------(C每日一题)

冒泡排序&#xff1a; 每次将相邻的两个数比较,将小的调到前头--升序 冒泡排序一个结论&#xff1a; n个数要进行n-1轮比较&#xff0c;第j轮要进行n-j次两两比较 循环体代码&#xff1a; int main() {int i, j,n,a[10],t;//n是几个数比较for(j1;j<n-1;j)//控制轮次for…

Bluetooth Mesh 入门学习干货,参考Nordic资料(更新中)

蓝牙网状网络&#xff08;Bluetooth mesh&#xff09;概念 概述 蓝牙Mesh Profile | Bluetooth Technology Website规范&#xff08;Mesh v1.1 后改名Mesh ProtocolMesh Protocol | Bluetooth Technology WebsiteMesh Protocol&#xff09;是由蓝牙技术联盟(Bluetooth SIG)开…

力扣刷题总结 栈与队列

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 一、栈和队列的基础知识 队列是先进先出&#xff0c;栈是先进后出。同时二者都是容器适配器而不是容器。 二、题目实战 232.用栈…

Unity AssetBundle学习笔记

目录 基础介绍 动态资源加载 更新和添加内容 打包策略 资源分组 频繁更新的资源 资源压缩 Unload&#xff08;true&#xff09;和Unload&#xff08;false&#xff09; Unload(false) Unload(true) 确定何时卸载 引用计数 场景和状态管理 资源使用频率 内存预算…

基于CNN神经网络的手写字符识别实验报告

作业要求 具体实验内容根据实际情况自拟&#xff0c;可以是传统的BP神经网络&#xff0c;Hopfield神经网络&#xff0c;也可以是深度学习相关内容。 数据集自选&#xff0c;可以是自建数据集&#xff0c;或MNIST&#xff0c;CIFAR10等公开数据集。 实验报告内容包括但不限于&am…

前端图片适配不同屏幕方案

预备知识&#xff1a; 设备独立像素,以下图的iphone12 Pro为例&#xff0c;390*844表示的就是设备独立像素&#xff08;DIP&#xff09;,也可以理解为CSS像素 物理像素&#xff08;设备像素&#xff09;&#xff0c;就是屏幕的分辨率&#xff0c;显示屏就是由一个个物理像素…

【vim 学习系列文章 3.1 -- vim 删除 ^M】

请阅读【嵌入式开发学习必备专栏 之 VIM 专栏】 文章目录 ^M 来源^M 删除 ^M 来源 在 Vim 中打开文件时&#xff0c;您可能会遇到行尾的 ^M 字符&#xff0c;这通常是因为文件使用了 Windows 风格的回车换行符&#xff08;CRLF&#xff09;&#xff0c;而不是 Unix/Linux 风格…

Java - 工厂设计模式

Java - 工厂设计模式 一. 简介二. 例子2.1 定义抽象类2.2 定义子类2.3 创建工厂2.4 测试 三. JDK中使用工厂模式的案例 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 工厂设计模式…

基于JAVA+SSM+VUE的前后端分离的大学竞赛管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着互联网技术的快速…

尽量避免删改List

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

【代码随想录】刷题笔记Day42

前言 这两天机器狗终于搞定了&#xff0c;一个控制ROS大佬&#xff0c;一个计院编程大佬&#xff0c;竟然真把创新点这个弄出来了&#xff0c;牛牛牛牛&#xff08;菜鸡我只能负责在旁边喊加油&#xff09;。下午翘了自辩课来刷题&#xff0c;这次应该是元旦前最后一刷了&…

苹果CMS超级播放器专业版无授权全开源,附带安装教程

源码介绍 超级播放器专业版v1.0.8&#xff0c;内置六大主流播放器&#xff0c;支持各种格式的视频播放&#xff0c;支持主要功能在每一个播放器内核中都相同效果。 搭建教程 1.不兼容IE浏览器 2.php版本推荐7.4 支持7.1~7.4 3.框架引入不支持同时引入多个播放器 json对接教…

搭建maven私服

maven maven简介 什么是maven&#xff1f; Maven这个单词来自于意第绪语&#xff08;犹太语&#xff09;&#xff0c;意为知识的积累。 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以…

数据结构与算法 - 查找

文章目录 第1关&#xff1a;实现折半查找第2关&#xff1a;实现散列查找 第1关&#xff1a;实现折半查找 代码如下&#xff1a; /*************************************************************date: April 2009copyright: Zhu EnDO NOT distribute this code. ***********…

记录一下imx6ull linux 5.10.9多点电容触摸屏驱动报错问题解决方法

最近再研究如何将linux 5.10.9移植到imx6ull&#xff0c;用的原子的开发板&#xff0c;在移植电容触摸屏驱动时报错gpio gpiochip0: (209c000.gpio): gpiochip_lock_as_irq: tried to flag a GPIO set as output for IRQ&#xff0c;如下图&#xff1a; 该错误的意思就是尝试将…

Flink1.17实战教程(第三篇:时间和窗口)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

[足式机器人]Part2 Dr. CAN学习笔记-Ch00 - 数学知识基础

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Ch00 - 数学知识基础 1. Ch0-1矩阵的导数运算1.1标量向量方程对向量求导&#xff0c;分母布局&#xff0c;分子布局1.1.1 标量方程对向量的导数1.1.2 向量方程对向量的导数 1.2 案例分析&#xf…