当前位置: 首页 > news >正文

C语言系列之——(6)C语言中的控制语句

c语言中的控制语句

  • 1.条件判断语句
    • 1.1 if
      • a if……else……
      • b 嵌套if
        • b.1悬空else问题
    • 1.2 switch
  • 2.循环执行语句
    • 2.1 do while
    • 2.2 while
    • 2.3 for
      • a. for的多表达式问题
      • b. for的无表达式问题
  • 3.转向语句
    • 3.1 break 和 continue
    • 3.2 goto
    • 3.3 return
      • a.return的使用规范

控制语句用于控制程序的执行流程,以实现程序的各种结构方式
C语言有三种结构方式:顺序结构选择结构循环结构,他们由特定语句的定义符组成
而控制语句则有九种:

这九种可分为以下三类:
条件判断语句/分支语句:if , switch
循环执行语句:do while , while , for
转向语句:break , goto , continue , return


1.条件判断语句

1.1 if

if语句的语法形式如下:

if(表达式)语句

表达式为真(成立),语句执行;反之则不执行

if默认只包含紧跟的第一条语句,若有多条待执行语句,需要用大括号{}将语句包含在内

if(表达式){语句1语句2……}

上面的条件判断只能实现一种情况下的行为执行,但实际中,我们常常想实现多种情况的对应行为执行,如:
不下雨就不带伞,下雨就带伞
如果bob爱吃辣,就给他辣条,如果爱吃酸,就给他柠檬,如果……
这时只用if一个一个情况识别显然不太可取,实际上,if可以“升级”为下面的几种形式:


a if……else……

对于 “不下雨就不带伞,下雨就带伞” 这种仅有两种对立,即只有a成立和a不成立的情况,可以使用if else语句,形式如下:

if(表达式1)语句1else语句2表达式1为真,就执行语句1,为假就执行语句2,相当于:如果(表达式1为真)(执行语句1)否则 就(执行语句2)

if else区分的两种情况是对立关系,即这两种情况互斥,且这两种情况组合起来就是全集(全部情况)


b 嵌套if

而在将一个全集分成多个部分,有大于等于三种互斥情况时,可以用嵌套if,核心是如果……否则……的嵌套条件判断,如下:

if(表达式1)语句1else{if(表达式2)语句2else{……}}上面的else里又有if可以简化成下面这种形式:if(表达式1)语句1elseif(表达式2)语句2elseif(表达式3)语句3elseif(……)……else语句n

上面代码的嵌套逻辑可用下图表示

当然if里也可以嵌套if(表达式1){if(表达式2)语句1else//表示满足表达式1情况下不满足表达式2{……}}else{……}

嵌套if重在如果……否则……的层层逻辑判断,在逻辑满足下if的嵌套是灵活多变的

b.1悬空else问题

请看下面代码:

#include<stdio.h>intmain(){inta=0;intb=2;if(a==1)if(b==2)printf("hehe\n");elseprintf("haha\n");return0;}

上面代码中的else并不是和if(a == 1)匹配,而是和if(b == 2)匹配,相当于:

#include<stdio.h>intmain(){inta=0;intb=2;if(a==1){if(b==2)printf("hehe\n");elseprintf("haha\n");}return0;}

C语言并不是和python一样靠缩进来划分代码块,而是只会按语法符号{}划分代码块作用域
else总是跟自己所在作用域内离它最近、尚未配对的 if匹配

要让else和if(a == 1)匹配,代码应改为:

#include<stdio.h>intmain(){inta=0;intb=2;if(a==1){if(b==2)printf("hehe\n");}elseprintf("haha\n");return0;}

1.2 switch

switch是一种特殊形式的 if else 结构,用于判断表达式(条件)有多个结果的情况
语法形式如下:

switch(表达式){case整型常量表达式1://case后必须是一个整型的常量,不能是1.0这种小数,也不能是k这种变量语句1case整型常量表达式2:语句2……}

switch的逻辑是:
先计算表达式的结果,然后从和结果匹配的case处开始依次执行后续语句

请看下面代码:

#include<stdio.h>intmain(){inta=1;intb;switch(a){case1:b=1;case2:b=2;case3:b=3;}printf("%d",b);return0;}

上面的代码展现出了使用switch语句的一个大坑,就是switch语句只会根据表达式不同的值从不同的case处开始,并不会局限于只实现一个case区域里的代码,而是从开始位置一直执行到尾,所以上面代码最后打印结果为3,而不是1

要想只执行一个分支的语句,需要在语句后加上break

switch(表达式){case整型常量表达式1:语句1break;case整型常量表达式2:语句2break;……}

换句话说,case决定了分支的入口,break决定了分支的出口

在使用 switch 语句的时候,我们经常可能遇到一种情况,比如 switch 后的表达式中的值无法匹配代码中的 case 语句的时候,这时候要不就不做处理,要不就得在 switch 语句中加入default子句

switch(表达式){case整型常量表达式1:语句1break;case整型常量表达式2:语句2break;……default:语句nbreak;}

default其实就相当于另一个有自己特殊对应值的case入口,这个入口的条件是:表达式的值和其他case的值都不匹配
所以,default和case的顺序没有一定的规定,default可以不放在末尾,甚至可以放在开头,因为它其实也就是一个条件特殊的入口
不过通常还是放在末尾


2.循环执行语句

2.1 do while

循环语句中do while的使用频率较低,其语法形式如下:

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

它的执行逻辑为:
开始先执行循环语句,再判断表达式真假
若表达式为真,则重复上诉操作;若为假,则停止执行循环语句

也就是说,do while的循环语句,至少会被执行一次

注意:do while默认只包含do紧跟的第一条语句,若有多条待执行语句,需要用大括号{}将语句包含在内

下面用打印1~10的数字来演示do while的使用:

#include<stdio.h>intmain(){inti=1;do{printf("%d ",i);i++;}while(i<11);return0;}

2.2 while

while语句的语法结构和if很相似:

while(表达式)循环语句

它的执行逻辑为:
开始先判断表达式真假
若表达式为真,执行循环语句,每执行完都会重新判断表达式真假,为真则重复上述步骤;
若为假,则停止执行循环语句

同样的,while也默认只包含紧跟的第一条语句,若有多条待执行语句,需要用大括号{}将语句包含在内

下面用打印1~10的数字来演示while的使用:

#include<stdio.h>intmain(){inti=1;while(i<11){printf("%d ",i);i++;}return0;}

2.3 for

for循环的使用频率较高,其复杂程度也比前两种更高,其语法形式如下:

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

其中:
表达式1用于循环变量的初始化
表达式2用于循环结束条件的判断
表达式3用于循环变量的调整

它的执行可用下图表示:

for 循环最先执行一次表达式 1 完成变量初始化,随后进入循环判断逻辑:
先运行表达式 2 做条件判定,若条件为假,循环直接结束;若条件为真,则执行循环语句。
执行循环语句时如果碰到 break,会直接终止整个循环;如果碰到 continue,会立刻停止当前循环剩下的代码,跳到表达式 3 执行变量调整。
正常走完循环语句后同样会执行表达式 3 更新变量,之后再次回到表达式 2 重新判断条件,不断重复该流程,直到表达式 2 判定为假退出循环。

【表达式1只在开始时执行这一次,后续就不会再执行表达式1】

同样的,while也默认只包含紧跟的第一条语句,若有多条待执行语句,需要用大括号{}将语句包含在内

下面用打印1~10的数字来演示for的使用:

#include<stdio.h>intmain(){for(inti=1;i<11;i++)printf("%d ",i);return0;}

a. for的多表达式问题

for在表达式1中可同时初始化多个同类型变量,多个变量使用逗号分隔,如:

for(inti=1,g=3,……;表达式2;表达式3)循环语句

for在表达式2和表达式3中同样也可以利用逗号运算符书写多段语句,但需要注意的是:

将多个表达式用逗号分隔组成多段语句,实际上构成了逗号表达式,执行时会依次执行每个表达式,最终将最后一个表达式的值作为整个逗号表达式的值,而这对靠判断真假来决定循环的终止或执行的表达式2来说是个大坑,请看下面代码:

#include<stdio.h>intmain(){for(inti=1,e=1;i>11,e<5;i++,e++)printf("%d+%d ",i,e);return0;}

上面的代码,表达式2的位置判断的是整个逗号表达式的真假,而该逗号表达式的值就是e < 5的值,与i > 11无关,所以即使i < 11,循环依旧进行

如果想实现多表达式作用的真假判断,可以借助逻辑运算符
下面代码用&&将两个表达式用并且关系关联起来,使循环开始即结束

#include<stdio.h>intmain(){for(inti=1,e=1;(i>11)&&(e<5);i++,e++)printf("%d+%d ",i,e);return0;}

b. for的无表达式问题

for 循环允许省略任意一个、两个甚至全部三个表达式,但底层执行逻辑不会改变程序运行到被省略的表达式位置时,等价于执行一条空语句

特别注意:
如果省略表达式 2(条件判断部分),该位置默认判定为恒真,循环会持续运行形成死循环;这种情况下想要退出循环,只能依靠循环体内的break语句,否则循环永远不会终止。


3.转向语句

在程序运行时,我们时常需要改变代码默认的顺序执行流程,循环里提前退出、跳过本轮代码、直接跳转到指定位置、结束函数等场景都十分常见。

C 语言提供了四类转向语句:break、continue、goto、return,用来灵活调整程序执行流向。

下面我们逐一讲解它们的作用与使用规范。

3.1 break 和 continue

break:直接永久终止当前循环,代码执行到 break 时,会立刻跳出当前循环,运行循环外部后续代码
continue:放弃本次循环剩下尚未执行的代码,直接开启下一轮循环

下面我们直接通过实际代码感受这两个转向语句:

#include<stdio.h>intmain(){printf("===== break 演示 =====\n");for(inti=1;i<=10;i++){if(i==5){break;// 直接终止整个循环}printf("%d ",i);}printf("\nbreak演示结束\n");printf("===== continue 演示 =====\n");for(inti=1;i<=10;i++){if(i==5){continue;// 跳过本次循环剩余代码,直接进入下一轮}printf("%d ",i);}printf("\ncontinue演示结束\n");return0;}

运行结果:
===== break 演示 =====
1 2 3 4
break演示结束
===== continue 演示 =====
1 2 3 4 6 7 8 9 10
continue演示结束

3.2 goto

goto语句实际包括goto和跳转标号 ,是一种比较特殊的语法,其形式如下:

goto跳转标号;//和取变量名一样给跳转标号取名跳转标号:

程序执行到goto语句时,会直接跳转到 跳转标号: 的这个位置执行后续代码
在想要跳出多层循环时,如果用break,每层循环都要有break语句,而用goto就会方便很多

#include<stdio.h>intmain(){// 双层循环for(inti=1;i<=3;i++){for(intj=1;j<=3;j++){printf("i=%d,j=%d\n",i,j);if(i==2&&j==2){gotoend_loop;}}}end_loop:// 跳转标号,名称自定义,末尾带冒号printf("已经跳出双层循环\n");return0;}

3.3 return

return 用于终止当前所在函数,将程序执行流程返回函数调用处;如果函数有返回值,还可以附带返回数据

main函数中执行return,代表直接结束整个程序
一旦执行return,函数内return之后的所有代码都不会运行

return 不受循环约束,在循环体内执行 return,会直接退出整个函数

注意区分:break只跳出循环,不能退出函数;return直接退出整个函数

请看下面代码:

#include<stdio.h>voidtest(){printf("函数开始运行\n");return;// 直接终止函数,下方printf不会执行printf("这段代码永远无法执行\n");}intmain(){printf("main函数开始\n");test();printf("main函数继续执行\n");return0;// 结束main函数,程序退出}

运行结果:
main 函数开始
函数开始运行
main 函数继续执行

a.return的使用规范

1.返回类型为void的函数,可不写return;当然也可以写return,但不能附带返回数值,只能按return ;这样书写,返回空语句
2.带有返回值的函数,正常应当使用return 数据;的形式返回匹配类型的值。
因为普通有返回值函数,如果代码执行结束仍没有执行return 值;,程序会触发未定义行为;
然而有一个特例,main函数允许省略末尾的 return,编译器会自动补充 return 0;
其他函数不享受该规则

http://www.cnnetsun.cn/news/4023297.html

相关文章:

  • m3u8-downloader 使用指南:一条命令完成 M3U8 视频下载与 MP4 合并
  • 为什么济南企业的济南英文网站建设必须避开这三个坑?资深开发者带你从0到1打造国际化品牌
  • 深度解析建设网站目的及功能定位如何驱动企业数字化转型与品牌增长
  • 2024年品牌网网站建设全解析:从0到1打造高转化率的专属营销阵地
  • 深度解析安徽省住房和城乡建设厅网站:从办事指南到工程监管的数字化变迁与未来展望
  • 电商型企业网站建设怎么才不翻车?老运营掏心窝子分享避坑指南
  • 从入门到精通揭秘苏州h5网站建设的全流程与避坑指南
  • 告别B站缓存吃灰:m4s-converter让m4s转MP4只需一分钟
  • 免费商用字体 Montserrat 完整上手指南:9 个字重、三大系列与网页优化实战
  • 企业微信如何通过AI机器人自动实现外部联系人和群的自动管理与消息触达
  • 从流量焦虑到品牌跃迁:揭秘上海中高端网站建设背后的底层逻辑与价值重构
  • 单链表专题(一)-应用篇:三道经典题吃透删除、反转与快慢指针
  • 网站建设所需材料:新手避坑指南与企业必备清单深度解析
  • Axure 全版本汉化指南:9、10、11 中文界面一次到位
  • 成都医院网站建设:打破信息孤岛,重塑医患信任的数字桥梁
  • 从一张照片到一件浮雕:用ImageToSTL完成图片转STL的全过程
  • 怎么建设免费网站从零开始打造个人品牌,低成本启动你的数字梦想
  • 别被忽悠了!揭秘靠谱山西网站建设公司背后的真相与干货
  • 免费搞定桌面分区整理:用 NoFences 把杂乱图标装进“围栏“,30 秒上手
  • 沧州网站建设优化背后的真相与企业如何通过低成本策略实现流量破局
  • 一键提升Illustrator工作效率20倍的免费脚本合集:5分钟从安装到上手
  • Wand-Enhancer开源增强工具全解析:本地补丁、手机远程控制与自定义脚本一次讲透
  • 揭秘外贸购物网站建设背后的真相:如何打造高转化率独立站并突破流量瓶颈
  • 邵阳网站建设公司:从草根逆袭到数字赋能,聊聊咱们本地建站那些真实现状
  • Windows APK安装器上手实操:从下载到跑通第一个安卓应用
  • 旅游网站建设目标:从平庸到卓越的全链路进阶策略
  • 厦门电商网站建设怎么避坑?2024年最新实战指南与企业选对服务商的核心逻辑
  • 潍坊企业网站建设如何避坑:从基础搭建到流量转化的底层逻辑深度解析
  • 凤阳网站建设哪家好?深耕本地市场十年,老张掏心窝子告诉你真相
  • 北京网站建设有哪些:揭秘正规企业建站的核心需求与避坑指南