第7章 C控制语句:分支和跳转

news2024/11/16 11:49:13

本章介绍以下内容:
关键字:if、else、switch、continue、break、case、default、goto
运算符:&&、||、?:
函数:getchar()、putchar()、ctype.h系列
如何使用if和if else语句,如何嵌套它们
在更复杂的测试表达式中用逻辑运算符组合关系表达式
C的条件运算符
switch语句
break、continue和goto语句
使用C的字符I/O函数:getchar()和putchar()
ctype.h头文件提供的字符分析函数系列
随着越来越熟悉C,可以尝试用C程序解决一些更复杂的问题。这时候,需要一些方法来控制和组织程序,为此C提供了一些工具。前面已经学过如何在程序中用循环重复执行任务。本章将介绍分支结构(如, if和switch),让程序根据测试条件执行相应的行为。另外,还将介绍C语言的逻辑运算符,使用逻辑运算符能在 while 或 if 的条件中测试更多关系。此外,本章还将介绍跳转语句,它将程序流转换到程序的其他部分。学完本章后,读者就可以设计按自己期望方式运行的程序。

7.1 if语句

if语句的通用形式如下:
if ( expression )
statement
如果对expression求值为真(非0),则执行statement;否则,跳过statement。与while循环一样,statement可以是一条简单语句或复合语句。if语句的结构和while语句很相似,它们的主要区别是:如果满足条件可执行的话,if语句只能测试和执行一次,而while语句可以测试和执行多次。
通常,expression 是关系表达式,即比较两个量的大小(如,表达式 x > y 或 c == 6)。如果expression为真(即x大于y,或c == 6),则执行statement。否则,忽略statement。概括地说,可以使用任意表达式,表达式的值为0则为假。
statement部分可以是一条简单语句,如本例所示,或者是一条用花括号括起来的复合语句(或块):
if (score > big)
printf("Jackpot!\n"); // 简单语句
if (joe > ron)
{              // 复合语句
joecash++;
printf("You lose, Ron.\n");
}

注意,即使if语句由复合语句构成,整个if语句仍被视为一条语句。

7.2 if else语句

注意,if else语句的通用形式是:
if ( expression )
statement1
else
statement2
如果expression为真(非0),则执行statement1;如果expression为假或0,则执行else后面的statement2。statement1和statement2可以是一条简单语句或复合语句。C并不要求一定要缩进,但这是标准风格。缩进让根据测试条件的求值结果来判断执行哪部分语句一目了然。

如果要在if和else之间执行多条语句,必须用花括号把这些语句括起来成为一个块。

7.2.1 另一个示例:介绍getchar()和putchar()

getchar()函数不带任何参数,它从输入队列中返回下一个字符。例如,下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:
ch = getchar();
该语句与下面的语句效果相同:
scanf("%c", &ch);

putchar()函数打印它的参数。例如,下面的语句把之前赋给ch的值作为字符打印出来:
putchar(ch);
该语句与下面的语句效果相同:
printf("%c", ch);

7.2.2 ctype.h系列的字符函数

 表7.1 ctype.h头文件中的字符测试函数

 表7.2 ctype.h头文件中的字符映射函数

7.2.3 多重选择else if

回忆一下,整个if else语句被视为一条语句,因此不必把嵌套的if else语句用花括号括起来。当然,花括号可以更清楚地表明这种特殊格式的含义。

7.2.4 else与if配对

规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花括号括起来

7.2.5 多层嵌套的if语句

从技术角度看,if else语句作为一条单独的语句,不必使用花括号。外层if也是一条单独的语句,也不必使用花括号。但是,当语句太长时,使用花括号能提高代码的可读性,而且还可防止今后在if循环中添加其他语句时忘记加花括号。

小结:用if语句进行选择
关键字:if、else
一般注解:
下面各形式中,statement可以是一条简单语句或复合语句。表达式为真说明其值是非零值。
形式1:
if (expression)
statement
如果expression为真,则执行statement部分。
形式2:
if (expression)
statement1
else
statement2
如果expression为真,执行statement1部分;否则,执行statement2部分。
形式3:
if (expression1)
statement1
else if (expression2)
statement2
else
statement3
如果expression1为真,执行statement1部分;如果expression2为真,执行statement2部分;否则,执行statement3部分。
示例:
if (legs == 4)
printf("It might be a horse.\n");
else if (legs > 4)
printf("It is not a horse.\n");
else   /* 如果legs < 4 */
{
legs++;
printf("Now it has one more leg.\n");
}

7.3 逻辑运算符

 表7.3 三种逻辑运算符

7.3.1 备选拼写:iso646.h头文件

表7.4 逻辑运算符的备选拼写 

7.3.2 优先级

!运算符的优先级很高,比乘法运算符还高,与递增运算符的优先级相同,只比圆括号的优先级低。&&运算符的优先级比||运算符高,但是两者的优先级都比关系运算符低,比赋值运算符高。

尽管对于该例没必要使用圆括号,但是许多程序员更喜欢使用带圆括号的第 2 种写法。这样做即使不记得逻辑运算符的优先级,表达式的含义也很清楚。

7.3.3 求值顺序

小结:逻辑运算符和表达式
逻辑运算符:
逻辑运算符的运算对象通常是关系表达式。!运算符只需要一个运算对象,其他两个逻辑运算符都需要两个运算对象,左侧一个,右侧一个。
逻辑表达式:
当且仅当expression1和expression2都为真,expression1 && expression2才为真。如果 expression1 或 expression2 为真,expression1 || expression2 为真。如果expression为假,!expression则为真,反之亦然。
求值顺序:
逻辑表达式的求值顺序是从左往右。一旦发现有使整个表达式为假的因素,立即停止求值。
示例:
6 > 2 && 3 == 3     真
!(6 > 2 && 3 == 3)   假
x != 0 && (20 / x) < 5 只有当x不等于0时,才会对第2个表达式求值

7.3.4 范围

&&运算符可用于测试范围。例如,要测试score是否在90~100的范围内,可以这样写:
if (range >= 90 && range <= 100)
printf("Good show!\n");
千万不要模仿数学上的写法:
if (90 <= range <= 100)  // 千万不要这样写!
printf("Good show!\n");

许多代码都用范围测试来确定一个字符是否是小写字母。例如,假设ch是char类型的变量:
if (ch >= 'a' && ch <= 'z')
printf("That's a lowercase character.\n");
该方法仅对于像ASCII这样的字符编码有效,这些编码中相邻字母与相邻数字一一对应。但是,对于像EBCDIC这样的代码就没用了。

7.4 一个统计单词的程序

7.5 条件运算符:?

C提供条件表达式(conditional expression)作为表达if else语句的一种便捷方式,该表达式使用?:条件运算符。该运算符分为两部分,需要 3 个运算对象。回忆一下,带一个运算对象的运算符称为一元运算符,带两个运算对象的运算符称为二元运算符。以此类推,带 3 个运算对象的运算符称为三元运算符。

通常,条件运算符完成的任务用 if else 语句也可以完成。但是,使用条件运算符的代码更简洁,而且编译器可以生成更紧凑的程序代码。

小结:条件运算符
条件运算符:?:
一般注解:
条件运算符需要3个运算对象,每个运算对象都是一个表达式。其通用形式如下:
expression1 ? expression2 : expression3
如果expression1为真,整个条件表达式的值是expression2的值;否则,是expression3的值。
示例:
(5 > 3) ? 1 : 2 值为1
(3 > 5) ? 1 : 2 值为2
(a > b) ? a : b 如果a >b,则取较大的值

7.6 循环辅助:continue和break

一般而言,程序进入循环后,在下一次循环测试之前会执行完循环体中的所有语句。continue 和break语句可以根据循环体中的测试结果来忽略一部分循环内容,甚至结束循环。

7.6.1 continue语句

3种循环都可以使用continue语句。执行到该语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代。如果continue语句在嵌套循环内,则只会影响包含该语句的内层循环。

对于for循环,执行continue后的下一个行为是对更新表达式求值,然后是对循环测试表达式求值

7.6.2 break语句

程序执行到循环中的break语句时,会终止包含它的循环,并继续执行下一阶段。

如果break语句位于嵌套循环内,它只会影响包含它的当前循环。

在for循环中的break和continue的情况不同,执行完break语句后会直接执行循环后面的第1条语句,连更新部分也跳过。嵌套循环内层的break只会让程序跳出包含它的当前循环,要跳出外层循环还需要一个break:

7.7 多重选择:switch和break

7.7.1 switch语句

程序扫描标签(这里指,case 'a' :、case 'b' :等)列表,直到发现一个匹配的值为止。然后程序跳转至那一行。如果没有匹配的标签怎么办?如果有default :标签行,就跳转至该行;否则,程序继续执行在switch后面的语句。

break语句在其中起什么作用?它让程序离开switch语句,跳至switch语句后面的下一条语句(见图7.4)。如果没有break语句,就会从匹配标签开始执行到switch末尾。

break语句可用于循环和switch语句中,但是continue只能用于循环中。

switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型)。case标签必须是整数类型(包括char类型)的常量或整型常量表达式(即,表达式中只包含整型常量)。不能用变量作为case标签。

switch的构造如下:
switch ( 整型表达式)
{
case 常量1:
语句   <--可选
case 常量2:
语句   <--可选
default :   <--可选
语句   <--可选
}

7.7.2 只读每行的首字符

7.7.3 多重标签

小结:带多重选择的switch语句
关键字:switch
一般注解:
程序根据expression的值跳转至相应的case标签处。然后,执行剩下的所有语句,除非执行到break语句进行重定向。expression和case标签都必须是整数值(包括char类型),标签必须是常量或完全由常量组成的表达式。如果没有case标签与expression的值匹配,控制则转至标有default的语句(如果有的话);否则,将转至执行紧跟在switch语句后面的语句。
形式:
switch ( expression )
{
case label1 : statement1//使用break跳出switch
case label2 : statement2
default   : statement3
}
可以有多个标签语句,default语句可选。
示例:
switch (choice)
{
case 1 :
case 2 : printf("Darn tootin'!\n"); break;
case 3 : printf("Quite right!\n");
case 4 : printf("Good show!\n"); break;
default: printf("Have a nice day.\n");
}
如果choice的值是1或2,打印第1条消息;如果choice的值是3,打印第2条和第3条消息(程序继续执行后续的语句,因为case 3后面没有break语句);如果choice的值是4,则打印第3条消息;如果choice的值是其他值只打印最后一条消息。

7.7.4 switch和if else

如果是根据浮点类型的变量或表达式来选择,就无法使用 switch。如果根据变量在某范围内决定程序流的去向,使用 switch 就很麻烦,这种情况用if就很方便:
if (integer < 1000 && integer > 2)
使用switch要涵盖以上范围,需要为每个整数(3~999)设置case标签。但是,如果使用switch,程序通常运行快一些,生成的代码少一些。

7.8 goto语句

小结:程序跳转
关键字:break、continue、goto
一般注解:
这3种语句都能使程序流从程序的一处跳转至另一处。

break语句:
所有的循环和switch语句都可以使用break语句。它使程序控制跳出当前循环或switch语句的剩余部分,并继续执行跟在循环或switch后面的语句。
示例:
switch (number)
{
case 4: printf("That's a good choice.\n");
break;
case 5: printf("That's a fair choice.\n");
break;
default: printf("That's a poor choice.\n");
}

continue语句:
所有的循环都可以使用continue语句,但是switch语句不行。continue语句使程序控制跳出循环的剩余部分。对于while或for循环,程序执行到continue语句后会开始进入下一轮迭代。对于do while循环,对出口条件求值后,如有必要会进入下一轮迭代。
示例:
while ((ch = getchar()) != '\n')
{
if (ch == ' ')
continue;
putchar(ch);
chcount++;
}
以上程序段把用户输入的字符再次显示在屏幕上,并统计非空格字符。

goto语句:
goto语句使程序控制跳转至相应标签语句。冒号用于分隔标签和标签语句。标签名遵循变量命名规则。标签语句可以出现在goto的前面或后面。
形式:
goto label ;
label : statement
示例:
top : ch = getchar();
if (ch != 'y')
goto top;
7.9

7.9 关键概念

7.10 本章小结

本章介绍了很多内容,我们来总结一下。if语句使用测试条件控制程序是否执行测试条件后面的一条简单语句或复合语句。如果测试表达式的值是非零值,则执行语句;如果测试表达式的值是零,则不执行语句。if else语句可用于二选一的情况。如果测试条件是非零,则执行else前面的语句;如果测试表达式的值是零,则执行else后面的语句。在else后面使用另一个if语句形成else if,可构造多选一的结构。
测试条件通常都是关系表达式,即用一个关系运算符(如,<或==)的表达式。使用C的逻辑运算符,可以把关系表达式组合成更复杂的测试条件。
在多数情况下,用条件运算符(?:)写成的表达式比if else语句更简洁。
ctype.h系列的字符函数(如,issapce()和isalpha())为创建以分类字符为基础的测试表达式提供了便捷的工具。
switch 语句可以在一系列以整数作为标签的语句中进行选择。如果紧跟在 switch 关键字后的测试条件的整数值与某标签匹配,程序就转至执行匹配的标签语句,然后在遇到break之前,继续执行标签语句后面的语句。
break、continue和goto语句都是跳转语句,使程序流跳转至程序的另一处。break语句使程序跳转至紧跟在包含break语句的循环或switch末尾的下一条语句。continue语句使程序跳出当前循环的剩余部分,并开始下一轮迭代。


 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot的配置文件(properties与yml)

文章目录 1. 配置文件的作用2. 配置文件格式3. 配置文件的使用方法3.1. properties配置文件3.1.1. 基本语法和使用3.1.2. properties优缺点分析 3.2. yml配置文件3.2.1. 基本语法与使用3.2.2. yml中单双引号问题3.2.3. yml配置不同类型的数据类型及null3.2.4. 配置对象3.2.5. 配…

百日筑基篇——Linux中文本工具应用(Linux入门六)

百日筑基篇——Linux中文本工具应用&#xff08;Linux入门六&#xff09; 文章目录 前言一、文本搜索工具 **grep**二、流式文本处理工具 **sed**三、文本处理工具 **awk**总结 前言 在Linux中&#xff0c;通常会使用一些工具来处理文本以获得所需的内容。而Linux中的文本处理…

python编程小游戏 五子棋,python编程小游戏简单的

大家好&#xff0c;本文将围绕python编程小游戏如何停止展开说明&#xff0c;python编程小游戏日语教程是一个很多人都想弄明白的事情&#xff0c;想搞清楚python编程小游戏超级玛丽需要先了解以下几个事情。 今天分享一个有趣的Python游戏库freegames&#xff0c;它里面包含经…

前端新手学习路线

文章目录 前端学习路线&#xff01;特点符号表大纲前言 - 学编程需要的特质一、前端入门⭐️ 开发工具浏览器编辑器文档笔记 ⭐️ HTML⭐️ CSS⭐️ JavaScript✅ ES6 特性 二、巩固基础前端基础知识计算机基础✅ 算法和数据结构✅ 计算机网络✅ 操作系统 软件开发基础✅ 设计模…

Kafka 入门到起飞 - 什么是 HW 和 LEO?何时更新HW和LEO呢?

上文我们已经学到&#xff0c; 一个Topic&#xff08;主题&#xff09;会有多个Partition&#xff08;分区&#xff09;为了保证高可用&#xff0c;每个分区有多个Replication&#xff08;副本&#xff09;副本分为Leader 和 Follower 两个角色&#xff0c;Follower 从Leader同…

【数据结构】实现顺序表

目录 一.介绍顺序表二.实现顺序表1.创建多文件2.顺序表的存储方式3.函数的声明4.初始化顺序表5.清理顺序表6.打印顺序表7.扩容8.尾插8.尾删9.头插10.头删11.查找12.修改13.在pos位置插入13.在pos位置删除 三.全部代码1.SeqList.h2.SeqList.c3.Test.c 一.介绍顺序表 顺序表是用…

【佳佳怪文献分享】使用点云从半监督到全监督房间布局估计

标题&#xff1a;From Semi-supervised to Omni-supervised Room Layout Estimation Using Point Cloud 作者&#xff1a;Huan-ang Gao, Beiwen Tian, Pengfei Li, Xiaoxue Chen, Hao Zhao, Guyue Zhou , Yurong Chen and Hongbin Zha 来源&#xff1a;2023 IEEE Internation…

Android系统-线程-消息处理机制

引言&#xff1a; Android应用消息处理机制是怎么样的呢&#xff1f; 跟Native&#xff0c;Linux底层都有些什么关系呢&#xff1f; 概念与理解&#xff1a; Android应用程序是通过消息来驱动的。 1&#xff09;应用程序的每一个线程在启动的时候&#xff0c;都可以首先在内…

Swagger-ui在idea中的使用

1.添加依赖 <!--添加swagger2相关概念--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><!--添加swagger-ui相关功能--><de…

【贪心+堆】CF1701 D

Problem - 1701D - Codeforces 题意&#xff1a; 思路&#xff1a; 手推样例可知&#xff1a; 一开始想的是&#xff0c;把这些区间按右端点排序&#xff0c;然根据排序后的贪心 事实上不是这样的&#xff0c;而是要把有可能的区间扔进堆里&#xff1a; 感觉这种带堆的贪心&…

【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总

【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总 TI编译器分类 在CCS按照目录下 有个名为${CG_TOOL_ROOT}的目录 其下就是当前工程的编译器 存放目录为&#xff1a; C:\ti\ccs1240\ccs\tools\compiler按类型分为五种&#xff1a; ti-cgt-arm…

J‘meter 连接 MySQL 数据库脚本

1、创建线程组 2、创建 JDBC Connection Configuration 3、创建 JDBC Request 4、最终创建的目录 5、重点来了 5.1 在百度中下载个 MySQL-connector-Java-8.0.28.jar&#xff0c;放在 jmeter 的 bin 目录下 5.2 在测试计划中&#xff0c;将 jar 包添加到脚本中 5.3 输入参…

如何查看mysql中各个表的数据大小

1.SHOW VARIABLES LIKE datadir; 这会显示 MySQL 数据目录的路径。在这个路径下&#xff0c;你可以找到每个数据库的文件夹&#xff0c;每个数据库文件夹中会包含各个表的 .ibd 文件。 2.进入对应的目录 3.进入对应的db&#xff0c;例如我自己的db为test 4.如果我们想以M为单…

在Gazebo中添加悬浮模型后,利用键盘控制其移动方法

前段时间写了文章&#xff0c;通过修改sdf、urdf模型的方法&#xff0c;在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落&#xff1a;在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落&#xff1a;修改sdf、urdf模型_sagima_sdu的博客-CSDN博客 今天讲…

2401. 最长优雅子数组;1111. 有效括号的嵌套深度;2134. 最少交换次数来组合所有的 1 II

2401. 最长优雅子数组 核心思想&#xff1a;滑动窗口。如何知道当前值与以前的值是否and为0很重要&#xff0c;这是这道题目的关键&#xff0c;and操作会把1变成0&#xff0c;但是不会把0变成1&#xff0c;所以当前值x要和前面的值两两and为0意味着&#xff0c;你要使前面的值…

Vim的插件管理器之Vundle

1、安装Vundle插件管理器 Vim可以安装插件&#xff0c;但是需要手动安装比较麻烦&#xff0c;Vim本身没有提供插件管理器&#xff0c;所以会有很多的第三方的插件管理器&#xff0c;有一个vim的插件叫做 “vim-easymotion”&#xff0c;在它的github的安装说明里有列出对于不同…

比ChatGPT更强的星火大模型V2版本发布!

初体验 测试PPT生成 结果&#xff1a; 达到了我的预期&#xff0c;只需要微调就可以直接交付&#xff0c;这点比ChatGPT要强很多. 测试文档问答 结果&#xff1a; 这点很新颖&#xff0c;现在类似这种文档问答的AI平台收费都贵的离谱&#xff0c;星火不但免费支持而且效果也…

vue项目报错:node:internal/modules/cjs/loader:1080

运行项目报错&#xff1a; 原因&#xff1a; 看划线的地方&#xff0c;中文乱码导致找不见模块了 解决方案 将路径上的中文改为英文即可&#xff0c;项目命名最好只有英文、下划线&#xff08;_&#xff09;、数字、横杠&#xff08;-&#xff09;等英文符号组成

MATLAB图形窗口固定

起因是上次作图的时候写了&#xff1a; clc clear close all 这三个典型的刷新语句 清空工作区、命令行并且关闭图窗 就导致每次我把图窗拉到合适的位置观察&#xff0c;再一次点击运行都会重新刷新在出生点&#xff08;x&#xff09; 所以想把图窗固定在某个位置 显然更…

解决爬虫上下行传输效率问题的实用指南

嗨&#xff0c;大家好&#xff01;作为一名专业的爬虫程序员&#xff0c;我们经常会面临上下行传输效率低下的问题。在处理大量数据时&#xff0c;如果传输效率不高&#xff0c;可能会导致爬虫任务速度慢&#xff0c;甚至中断。今天&#xff0c;我将和大家分享一些解决爬虫上下…