【跟着陈七一起学C语言】今天总结:C语言的if选择结构和循环结构
友情链接:专栏地址
知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的错误,同时方便本人的基础复习,也希望能帮助到大家
最好的好人,都是犯过错误的过来人;一个人往往因为有一点小小的缺点,将来会变得更好。如有错漏之处,敬请指正,有更好的方法,也希望不吝提出。最好的生活方式就是和努力的大家,一起奔跑在路上
文章目录
- 【思维导图】
- 🚀选择结构设计
-
- ⛳一、if语句
-
- 🎈(一)if语句的三种形态
- 🎈(二)if语句的嵌套
- ⛳二、switch语句循环结构设计
- ⛳三、switch和if else的选择
- ⛳四、拓展:goto语句
- 🚀循环结构设计
-
- ⛳一、三种基本循环
-
- 🎈(一)while语句实现循环
- 🎈(二)for语句实现循环
- 🎈(三)do...while语句实现循环
- ⛳二、while和do...while循环的比较
- ⛳三、循环中的特殊控制:continue 与 break
- ⛳四、循环嵌套
- ⛳五、如何选择循环
【思维导图】
我的总结方式一般是先搞一段程序过来,然后再逐行的学习相关的知识点
🚀选择结构设计
⛳一、if语句
if ( expression ) statement
expression称为测试条件,if 和 if else 语句使用测试条件来判断执行哪些语句。所有非零值都被视为 true,零被视为false。测试通常涉及关系表达式(比较两个值)、逻辑表达式(用逻辑运算符组合或更改其他表达式)
如果对expression求值为真(非0),则执行statement;否则,跳过 statement,statement可以是一条简单语句或复合语句。通常,expression 是关系表达式,例如:
if(x>=0)printf("%d",x);
拓展:
1.C并不要求一定要缩进,但这是标准风格。缩进让根据测试条 件的求值结果来判断执行哪部分语句一目了然。
2.要记住一个通用原则,如果要测试两个条件,应该使用逻辑运算符把两个完整的测试表达式组合起来。例如:
if (a < x < z) // 错误,没有使用逻辑运算符 …if (ch != 'q' && != 'Q') // 错误,缺少完整的测试表达式 … //正确的方式:用逻辑运算符连接两个关系表达式 if (a < x && x < z) // 使用&&组合两个表达式 … if (ch != 'q' && ch != 'Q') // 使用&&组合两个表达式 …
🎈(一)if语句的三种形态
简单形式的if语句可以让程序选择执行一条语句,或者跳过这条语句。 C还提供了if else形式,可以在两条语句之间作选择。但是如果要在if和else之间执行多条语句,必须用花括号把这些语句括起来成为一个块。
if ( expression )statement1
else statement2
1.如果…那么
#include <stdio.h>int main(void) {int salary;printf("你月薪是多少");scanf("%d",&salary);if (salary < 20000) {printf("你是一个好人, 我还不想谈恋爱\\n");}return 0;
}
2.如果…那么…否则
#include <stdio.h>int main(void) {int salary;printf("你月薪是多少");scanf("%d",&salary);if (salary < 20000) {printf("你是一个好人, 我还不想谈恋爱\\n");} else {printf("我没有什么要求, 只要你对我好就行\\n");}return 0;
}
3.如果…那么…,或者…那么…,否则…
#include <stdio.h>int main(void)
{int salary;char houseRet[8]; //是否有房char carRet[8]; //是否有车printf("你月薪是多少");scanf("%d",&salary);printf("你有房吗");scanf("%s",carRet);printf("你有车吗");scanf("%s",carRet);if (salary < 20000) {printf("你是一个好人, 我还不想谈恋爱\\n");} else if (houseRet == "有") {printf("我其实没有什么要求,只要你对我好\\n");} else if (carRet == "有") {printf("我还不错哦, 以后再联系\\n");} else {printf("有缘再见\\n");}return 0;
}
🎈(二)if语句的嵌套
实例: 求 3 个数的最大值
#include <stdio.h>int main(void) {int x, y, z; printf("请输入 3 个整数:\\n"); scanf("%d%d%d",&x,&y,&z);if (x > y) {if (x > z) {printf("最大值是:%d\\n",x);} else {printf("最大值是:%d\\n",z);}} else {if (y > z) {printf("最大值是:%d\\n",y);} else {printf("最大值是:%d\\n",z);}}return 0;
}
嵌套的常见错误(配对错误),else与前面最近的,而且还没有配对的 if匹配,错误避免方法:
- 严格使用 { }
- 先写{}再写里面的内容
- 保持良好的“缩进
⛳二、switch语句循环结构设计
使用条件运算符和 if else 语句很容易编写二选一的程序。然而,有时程序需要在多个选项中进行选择。可以用if else if…else来完成。但是,大多数情况下使用switch语句更方便。
switch语句的作用是根据表达式的值,使流程跳转到不同的语句。switch语句的一般形式如下:
switch(表达式)
{case 常量表达式1:语句1case 常量表达式2:语句2case 常量表达式3:语句3default 表达式1:语句1
}
例如:
# include <stdio.h>
int main( ){char grade;scanf(" %c", &grade);printf(" Your score:" );switch(grade){case 'A': printf("85~ 100\\n") ;break;case 'B': printf("70~ 84\\n"); break;case 'C': printf("60~69\\n"); break;case 'D': printf("< 60\\n") ; break;default: printf("enter data error!\\n" );}
return 0;
}
-
程序分析:等级grade定义为字符变量,从键盘输人一个大写字母,赋给变量grade,switch得到grade的值并把它和各case中给定的值(‘A’,‘B’,‘C’,‘D’之一)相比较,如果和其中之一相同(称为匹配),则执行该case后面的语句(即printf语句)。输出相应的信息。如果输入的字符与’A’,‘B’,‘C’,‘D’ 都不相同,就执行default 后面的语句,输出“输入有错”的信息
-
可以没有default标号,此时如果没有与switch表达式相匹配的case常量,则不执行任何语句,流程转到switch语句的下一个语句。
-
各个case标号出现次序不影响执行结果。例如可以先出现default标号,再出现“case ‘D’: …”,然后是“case ‘B’: …”
-
switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型)。case标签必须是整数类型(包括char类型)的常量或整型常量表达式 (即,表达式中只包含整型常量)。不能用变量作为case标签。
-
case标号只起标记的作用。在执行switch语句时,根据switch表达式的值找到匹配的入口标号,并不在此进行条件检查,在执行完一个case标号后面的语句后,就从此标号开始执行下去,不再进行判断。例如在例4.6中,如果在各case子句中没有break 语句,将
连续输出:Your score:85~ 100 70~ 84 60~ 69 60 enter data error !
-
break语句在其中起什么作用?它让程序离开switch语句,跳至switch 句后面的下一条语句。如果没有break语句,就会从匹配标签开 始执行到switch末尾,如第4点中的情况。一般情况下,在执行一个case子句后,应当用break语句使流程跳出switch结构,即终止switch语句的执行。最后一个case子句(今为default 子句)中可不必加break语句,因为流程已到了switch结构的结束处。
-
在case子句中虽然包含了一个以上执行语句,但可以不必用花括号括起来,会自动顺序执行本case标号后面所有的语句。当然加上花括号也可以。
-
多个case标号可以共用一组执行语句,例如:当grade 的值为’A’,‘B’ ,'C’时都执行同一组语句,输出“≥60”。然后换行。
case ' A': case 'B' : case 'C' : printf("> 60\\n" ) ; break;
拓展:
1.以下错误,在 vs/vc 中有提示,但是仍可以通过编译。 在 gcc 编译器中,不能通过编译
switch(c) { case 1:int x = 0; //错误!printf("c=1");break; case 2:.......//应修改为 case 1: {int x = 0; printf("c=1"); } break; case 2:......
2.continue语句:
break语句可用于循环和switch语句中,但是continue只能用于循环中。尽管如此,如果switch语句在一个循环中,continue便可作为 switch语句的一部分。
这种情况下,就像在其他循环中一样,continue让程序跳出循环的剩余部分,包括switch语句的其他部分。
⛳三、switch和if else的选择
何时使用switch?何时使用if else?经常会别无选择
如果是根据浮点类型的变量或表达式来选择,就无法使用 switch。如果根据变量在某范围内决定程序流的去向,使用 switch 就很麻烦,这种情况用if就很方便:
if (integer < 1000 && integer > 2)
使用switch要涵盖以上范围,需要为每个整数(3~999)设置case标签。但是,如果使用switch,程序通常运行快一些,生成的代码少一些。
⛳四、拓展:goto语句
早期版本的BASIC和FORTRAN所依赖的goto语句,在C中仍然可用。但是C和其他两种语言不同,没有goto语句C程序也能运行良好。Kernighan和 Ritchie提到goto语句“易被滥用”,并建议“谨慎使用,或者根本不用”
goto语句有两部分:goto和标签名。标签的命名遵循变量命名规则,如下所示:
goto part2
要让这条语句正常工作,函数还必须包含另一条标为part2的语句,该 语句以标签名后紧跟一个冒号开始:
part2: printf("Refined analysis:\\n");
避免使用goto:
程序中使用其他形式比使用goto的条理更清晰。当多种情况混在一起时,这种差异更加明显。过度地使用 goto 语句,会让程序错综复杂。如果不熟悉goto 语句,就不要使用它
🚀循环结构设计
⛳一、三种基本循环
🎈(一)while语句实现循环
while循环的通用形式如下:
while ( expression ) statement
- statement部分可以是以分号结尾的简单语句,也可以是用花括号括起来的复合语句。
- expression部分是循环条件。执行循环体的次数是由循环条件控制的,它也称为循环条件表达式。当此表达式的值为“真”(以非0值表示)时,就执行循环体语句;为“假”(以0表示)时,就不执行循环体语句。
拓展:
1.伪代码
把sum初始化为0 提示用户输入数据 读取用户输入的数据 当输入的数据为整数时, 输入添加给sum, 提示用户进行输入, 然后读取下一个输入 输入完成后,打印sum的值
伪代码(pseudocode),是一种用简单的句子表示程序思路的方法,它与计算机语言的形式相对应。伪代码有助于设计程序的逻辑。确定程序的逻辑无误之后,再把伪代码翻译成实际的编程代码。使用伪代码的好处之一是,可以把注意力集中在程序的组织和逻辑上,不用在设计程序时还要分心如何用编程语言来表达自己的想法。例如,可以用缩进来代表一块代码,不用考虑C的语法要用花括号把这部分代码括起来。
2.C风格读取循环status = scanf("%ld", &num); while (status == 1) { /* 循环行为 */ status = scanf("%ld", &num); }
可以用以下代码替换
while (scanf("%ld", &num) == 1) { /*循环行为*/ }
第二种形式同时使用scanf()的两种不同的特性。首先,如果函数调用成功,scanf()会把一个值存入num。然后,利用scanf()的返回值(0或1,不是 num的值)控制while循环,因为每次迭代都会判断循环的条件,所以每次迭代都要调用scanf()读取新的num值来做判断
死循环:当循环判断条件永远为真的时候即是一个死循环
while(1) {语句
}
🎈(二)for语句实现循环
while循环是不确定循环(indefinite loop)。所谓不确定循环,指 在测试表达式为假之前,预先不知道要执行多少次循环。另外,还有一类是计数循环(counting loop)。这类循环在执行循环之前就知道要重复执行多少次,即for循环
for语句的一般形式为
for(表达式1;表达式2;表达式3)语句
- 表达式1:设置初始条件,只执行一次。可以为零个、一个或多个变量设置初值(如i=1)。
- 表达式2:是循环条件表达式,用来判定是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环。
- 表达式3:作为循环的调整,例如使循环变量增值,它是在执行完循环体后才进行的。
拓展:
1.表达式 1、表达式 2、表达式 3, 这 3 个表达式的任意一个或多个,都可以省略! 但是其中的“;”不可以省略!
for (; ; ) {循环体 } //相当于: while (1) {循环体 }for ( ; test ; ) {循环体 } //相当于: while ( test ) {循环体 }
2.在 C89 标准中,表达式 1 不能定义变量,在 C99 标准和 C++中,表达式 1 可以定义变量 表达式 1 中定义的变量仅在 for 循环中有效。
3.若省略表达式2且在循环体中没有设置循环结束条件,那么该循环将成为一个死循环
🎈(三)do…while语句实现循环
前面讲的while和for循环也叫入口条件循环,除了while语句以外,C语言还提供了do…while语句来实现循环结构,它是一种出口条件循环。
do…while语句的一般形式为
do语句
while (表达式) ;
其中的“语句”就是循环体。它的执行过程可以用图5.4表示。请注意do…while循环用N-S流程图的表示形式(图5.4(b))。先执行一次指定的循环体语句,后判别表达式,当表达式的值为非零(“真”)时,返回重新执行循环体语句,如此反复,直到表达式的值等于0(“假”)为止时循环结束
拓展:
特殊用法:
do { // 循环体 } while(0)
⛳二、while和do…while循环的比较
1.用while循环:
# include < stdio. h>int main( )
{int i,sum=0;printf(" please enter i,i=?");scannf("%d",&i);while(i<= 10){sum= sum+i;i++;}printf("sum=%d\\n",sum);return 0;
}
运行结果(两次):
please enter i,i=?1
sum = 55please enter i,i=?11
sum = 0
2.用do…while循环:
# include < stdio. h>
int main( )
{int i,sum= 0;printf(' please enter i,i=?");scanf("%d" ,&i);do{sum = sum+i;i++;}while(i< = 10);printf("sum=%d\\n",sum);return 0;
}
运行结果(两次):
please enter i,i=?1
sum = 55please enter i,i=?11
sum = 11
可以看到,当输入i的值小于或等于10时,二者得到的结果相同;而当i>10时,二者结果就不同了。这是因为此时对while循环来说,一次也不执行循环体(表达式“i<=10”的值为假),而对d…while循环语句来说则至少要执行一次循环体。可以得到结论:当while后面的表达式的第1次的值为“真”时,两种循环得到的结果相同;否则,二者结果不相同(指二者具有相同的循环体的情况)。
⛳三、循环中的特殊控制:continue 与 break
break :结束本层循环。
continue :结束本次循环,进入下一次循环
for 语句中的 continue
while 语句中的 continue
⛳四、循环嵌套
要点: 把内层的循环,看成一个完整的“大语句”
#include <stdio.h>// 一天想我几次?
// 24 小时,每秒一次
int main(void) {int count = 0;for (int i=0; i < 24; i++) {for (int j=0; j<60; j++) {for (int k=0; k<60; k++) {count++; printf("%d:%d:%d想你第%d次\\n",i,j,k,count);Sleep(1000);}}}printf("一天想你%d次\\n",count);return 0;
}
⛳五、如何选择循环
- 首先,确定是需要入口条件循环还是出口条件循环。通常,入口条件循环用得比较多,有几个原因。其一,一般原则是在执行循环之前测试条件比较好。其二,测试放在循环的开头,程序的可读性更高。另外,在许多应用中,要求在一开始不满足测试条件时就直接跳过整个循环。
- 一般而言,当循环涉及初始化和更新变量时,用for循环比较合适,而在其他情况下用while循环更好。
- 对于涉及索引计数的循环,用for循环更适合
行文至此,落笔为终。文末搁笔,思绪驳杂。只道谢不道别。早晚复相逢,且祝诸君平安喜乐,万事顺意。