文章目录
这就是你的人生------->流程控制三大结构
引言
众所周知,C语言是【结构化的】程序设计语言,那什么是结构化?这就得从我们的现实生活中说起,我们从出生就意味着我们将要一步一步的走向死亡,在此过程中,我们也许要做出或者被迫做出不同的选择,比如你是选择躺平还是不断的向前冲,即使你选择躺平,生活也会压迫着你往前走。这就是人在江湖飘,身不由己。我们就在选择与被选择中经历日升月落,花开花谢,四季循环。我们生活中发生的事情基本上都是由顺序,选择,循环所组成。相应在C语言中也有顺序,选择,循环三大结构,用来描述人类世界从而用程序去解决现实中的各样各样的问题,接下来就来介绍C语言的流程控制三大结构。
什么是语句?
C语句可分为以下五类: 1. 表达式语句 2. 函数调用语句 3. 控制语句 4. 复合语句 5. 空语句
本次介绍的是控制语句。
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:
1.条件判断语句也叫分支语句:if语句、switch语句;
2.循环执行语句:do while语句、while语句、for语句;
3.转向语句:break语句、goto语句、continue语句、return语句。
流程控制主要有三种结构:分别是顺序结构,分支结构和循环结构,这三种结构代表代码执行的顺序。
顺序结构
顺序结构是程序中最简单的,最基础的流程控制,我们之前写的代码都属于顺序结构(也就是从上往下依次执行),它没有固定的语法结构,程序会按照代码的先后顺序,依次执行,咋就不说。
分支语句(选择结构)
如果你选择没日没夜的摸鱼,那么毕业即失业,就要去搬砖了。
如果你打码打的键盘都烂了,那么毕业等于就业,成为一名优秀的程序员。、
这就是所谓的选择。
C语言提供了两种分支结构语句
- if语句
- switch语句
if语句
语法结构
//条件成立执行代码,否则什么也不做 if(表达式) 语句;
if的流程控制图
实践出真理,上代码(一)
int main() { int age = 0; printf("请输入你的年龄:>"); scanf("%d",&age); if (age >=18) { printf("你可以喝酒了!"); } if (age < 18) { printf("你只能喝营养快线。"); } return 0; }
if的加强版if else语句(双分支语句)
语法结构
//条件成立,执行if里面代码,否则执行else里面的代码 if(条件表达式){ //满足条件执行的代码 }else{ //不满足条件执行的代码 }
if ……else流程控制图
实践出真知,上代码(二)
int main() { int age = 0; printf("请输入你的年龄:>"); scanf("%d",&age); if (age >=18) { printf("你可以喝酒了!"); } else { printf("你只能喝营养快线。"); } return 0; }
代码一与代码二的效果是一样的,这就说明在某种条件下,多个单分支if语句与if……else语句是可以互逆的。
if 语句的超级加强版 if else if(多分支语句)
语法结构
//适用于检查多重条件 if(条件表达式){ 语句1; }else if(条件表示式){ 语句2; }else if(条件表示式){ 语句3; …… }else{ //上述条件都不成立执行此代码 }
if ……else if流程控制图
int main() { int age = 0; scanf("%d", &age); if (age < 18) { printf("少年\n"); } else if (age >= 18 && age < 30) { printf("青年\n"); } else if (age >= 30 && age < 50) { printf("中年\n"); } else if (age >= 50 && age < 80) { printf("老年\n"); } else { printf("老寿星\n"); } }
补充:
判断表达式的值
首先我们要知道的是C语言规定0代表假,非0的数代表真。其次,判断表达式的结果为真时判断表达式代表的值就是1。
代码块
一对{}就是一个代码块
悬空else
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; }
xmd可以思考思考它的结果是什么,这串代码非常容易令人判断错误,因为else到底是那个if的?这个无法判断也就无法知道程序所执行的结果。对于这串代码我把它直接复制到VS里面去,后发生一个细小的变化,这个变化蕴藏一个惊天的结论。接下来,就来观察一下,它在VS中的模样。
在VS中的代码
int main() { int a = 0; int b = 2; if (a == 1) if (b == 2) printf("hehe\n"); else printf("haha\n"); return 0; }
两份内容一模一样的代码,但是else的位置缺不一样,第一份代码是因为写这个代码的人本身代码风格不好,还有就是他用的工具不够强大,没有自动调整他所写的代码风格,像VS这种友好的工具,会自动去调成你所写的代码形式,会美化你的代码让它的可读性变强。像上面那段在VS中的代码,VS自动调整了else的位置,不是让它孤独的悬在空中,而是让它找到了自己的另一半if。从而我们可以知道else总是和最近if匹配。
结论:else的匹配:else是和它离的最近的if匹配的。
switch语句
switch语句也是多分支语句,它用于基于不同的条件;来执行不同的代码,当要针对变量设置一系列的特定值时选用switch
switch(表示式){ case value1: //表达式等于value1时要执行的代码 break; case value2: //表达式等于value2时要执行的代码 break; default: //表达式不等于任意一个value时要执行的代码 }
switch流程控制图
先来看看一个有问题的代码,见识一下case穿透
int main() { int day = 1; switch (day) { case 1: printf("星期一\n"); case 2: printf("星期二\n"); case 3: printf("星期三\n"); case 4: printf("星期四\n"); case 5: printf("星期五\n"); case 6: printf("星期六\n"); case 7: printf("星期天\n"); } return 0; }
结果如图
因为每个case后面没有加break去阻止程序往下走,所以case后面的情况都被执行了。
修改后的代码
int main() { int day = 1; switch (day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; case 6: printf("星期六\n"); break; case 7: printf("星期天\n"); break; } return 0; } //加上break就能该阻止时便能及时阻止,而不是一路执行下去
结果如图
有时候我们的需求变了:
- 1.输入1-5,输出的是“weekday”;
- 2.输入6-7,输出“weekend”
因为15都是输出weekday,67都是输出weekend,所以只需两条输出语言即可。
代码如下
int main() { int day = 1; 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; }
break语句 的实际效果是把语句列表划分为不同的分支部分。
编程好习惯一
在最后一个 case 语句的后面加上一条 break语句。 (之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句)。
default子句 如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结构就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,把下面的标签
default:
写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个switch语句中只能出现一条default子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
defalt语句可加可不加,加与不加取决于具体程序的要求,所以具体问题具体分析。
编程好习惯二
在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
语句之间的嵌套
为什么需要嵌套,因为我们所面对的问题不可能就只是单纯用分支语句,循环语句就能解决,往往需要判断语句和循环一句共同使用才能达到我们想要的效果,语句之间可以嵌套,同一语句也可以嵌套,比如典型同一语句嵌套就是双层for循环,接下来就能看看比较陌生的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);//m=3 ,n=5 return 0; }
循环结构
循环的目的
在实际问题中,有许多具有规律性的重复操作,因此在程序中要执行这类操作就要重复执行某些语句
C中的循环
在C语言中,主要有三种类型的循环语句
- for循环
- while循环
- do ……while循环
for循环
在程序中,一组被重复执行的语句被称为循环体,能否继续重复执行,取决于循环终止的条件,由循环体及
循环终止条件组成的语句,被称为循环语句
语法结构
for循环主要用于把某些代码重复若干次,通常跟计数有关。其语句结构如下
for(表达式1; 表达式2; 表达式3) 循环语句;
表达式1 表达式1为初始化部分,用于初始化循环变量的。
表达式2 表达式2为条件判断部分,用于判断循环时候终止。
表达式3 表达式3为调整部分,用于循环条件的调整/循环变量的更新。
for流程控制图
用for循环快读打印1~100的数字
int main() { int i = 0; //for(i=1/*初始化*/; i<=10/*判断部分*/; i++/*调整部分*/) for (i = 1; i <= 100; i++) { printf("%d ", i); } return 0; }
break和continue在for循环中
直接上代码
//代码1 #include <stdio.h> int main() { int i = 0; for(i=1; i<=10; i++) { if(i == 5) break; printf("%d ",i); } return 0; } //结果1 2 3 4 //break终止,breakn后面的代码都不执行 //代码2 #include <stdio.h> int main() { int i = 0; for(i=1; i<=10; i++) { if(i == 5) continue;//跳过本次循环进入下一轮循环 printf("%d ",i); } return 0; } //结果1 2 3 4 6 7 8 9 10
双层for循环(循环嵌套)
循环嵌套是指在一个循环语句里再定义一个循环语句的语法结构,例如在for循环里再嵌套一个for循环,这样的for循环语句我们称之为双层for循环
1.我们把里面的循环称之为内层循环,外面的 称之为外层循环
2.外层循环循环一次,内层循环从头到尾执行一遍
代码示范
//打印直角三角型 int main() { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { printf("*"); } printf("\n"); } } //思路:先分析要打印的图形,观察行与列关系。再确定内层循环的算法 //打印九九乘法表 int main() { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { printf("%d*%d=%2d ",i,j,i*j); } printf("\n"); } }
for循环小结
- for循环可以重复执行某些重复的代码
- for循环可以超重复执行不同的代码,因为我们有计数器
- for循环可以重复执行某些操作,比如算术运算加法操作
- 双层for循环:外层循环循环一次,内层循环从头到尾执行一遍
- for循环的循环条件是和数字直接相关的循环
- 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
- 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
while循环
while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不满足条件时结束循环
while语句的语法结构
while(条件表达式){ //循环体语句; }
执行思路:
- 1.先执行条件表达式,如果条件为true,则执行循环体代码,反之,则退出循环,执行后面的代码
- 2.执行循环体代码
- 3.循环体代码执行完毕后,程序会继续判断执行条件表达式,如果条件还是为true则继续执行循环体,直到循环条件为false时,整个循环体过程才会结束
流程控制图
既然是循环我们也可以用while循环打印1~100的数字
int main() { int i = 1; while (i <= 100) { printf("%d ", i); i++; } return 0; }
上面的代码已经帮我了解了 while 语句的基本语法,那我们再了解一下:
while语句中的break和continue
//break 代码实例 #include <stdio.h> int main() { int i = 1; while(i<=10) { if(i == 5) break; printf("%d ", i); i = i+1; } return 0; }
这里代码输出的结果是什么?
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6 7 8 9 10
1 2 3 4 6 7 8 9 10
总结: break在while循环中的作用:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 所以:while中的break是用于永久终止循环的。
continue介绍
//continue 代码实例1 #include <stdio.h> int main() { int i = 1; while(i<=10) { if(i == 5) continue; printf("%d ", i); i = i+1; } return 0; } //结果1 2 3 4
总结: continue
在while循环中的作用就是: continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行, 而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
do ……while循环
do……while 语句其实就是while语句的一个变种,该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环
do……while语句的语法结构如下
do { //循环体代码- 条件表达式为true时重复执行循环体代码 }
执行思路:
- 1.先执行一次循环体代码
- 2.再执行条件表达式,如果结果为true,则继续执行循环体代码,如果为false,则退出循环,继续执行后面的代码
注意:先执行循环体语句,再判断,我们就会发现do……while循环语句至少会执行一次循环体。
do……while流程控制图
使用do……while求n的阶乘
int main() { int num = 0; int i = 1; int sum = 1; scanf("%d", &num); do { sum *= i; i++; }while(i <= num); printf("%d", sum); }
do while循环中的break和continue
#include <stdio.h> int main() { int i = 10; do { if (5 == i) break; printf("%d\n", i); } while (i < 10); return 0; } //10 #include <stdio.h> int main() { int i = 10; do { if (5 == i) continue; printf("%d\n", i); } while (i < 10); return 0; } //10
循环小结
- C中循环有for,while,do……while
- 三种循环很多情况下都可以相互交替使用
- 如果是用来计次数,跟数字有关的,三者使用基本相同,更推荐使用for
- while,do……while可以做更加复杂的判断条件,比for循环灵活一些
- while和do…… while执行顺序不一样,while先判断后执行,do……while先执行一次,再判断执行
- while和do…… while执行次数不一样,do……while至少会执行一次循环体,而while可能一次也不执行
- 重点学习for循环语句,因为它写法更简洁
continue 和break
continue关键字用于立即跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)。
如:吃5个包子,第三个有虫子,就扔掉第三个,继续吃第四个第五个包子
吃包子代码
int main() { int i = 0; for ( i= 1; i <= 5; i++) { if (i == 3) { continue; } printf("我吃了第%d个包子能\n", i); } return 0; } //我吃了第1个包子! //我吃了第2个包子! //我吃了第4个包子! //我吃了第5个包子!
break关键字
break关键字用于立即跳出整个循环(循环结束)
如:吃五个包子,吃到第三个又发现了一条虫,就没胃口吃了。
代码示范
int main() { int i = 0; for ( i= 1; i <= 5; i++) { if (i == 3) { break; } printf("我吃了第%d个包子!\n", i); } return 0; } //我吃了第1个包子! //我吃了第2个包子!
goto语句(了解)
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。 但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过 程。
例如:一次跳出两层或多层循环。 多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。
代码示范
int main() { int num = 0; scanf("%d", &num);//输入三直接跳出循环执行printf for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { for (int k = 0; k < 9; k++) { if (num == 3) { goto error; } } } } error: if (num == 3) { printf("你是猪\n"); } return 0; }
结束语
“冬天从这里夺去的,春天会交还给你。” – 海涅