S2-分支语句和循环语句
分支语句
if
switch
循环语句
while
do......while
for
goto语句
1、什么是语句?
C语言可分为以下五类:
1.表达式语句
2.函数调用语句
3.控制语句
4.复合语句
5.空语句
C语言是一门结构化的程序设计语言
C语言支持三种结构:
1.顺序结构
2.选择结构
3.循环结构
本章主要介绍的是控制语句。
控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持的三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。
可分为三类:
1.条件判断语句也叫分支语句:if语句、switch语句;(也就是选择结构)
2.循环执行语句:do......while语句、while语句、for语句;(也就是循环语句)
3.转向语句:break语句、goto语句、continue语句、return语句。
2.分支语句(选择结构)
如果你现在好好学习,你期末就不会挂科。
如果你不学习,你期末等着挂科,补考吧。
这就是一个选择。
2.1 if语句
2.1.1 if语句的三种形式
那三种语法结构是怎么样的?
1.单分支if语句
//单分支if语句 2. if(表达式) 3. 语句;
(1)非0为真,0为假
(2)功能:如果表达式的值为真,则执行其后面的语句,否则不执行该语句。
2.双分支if语句
1. //双分支if语句 2. if(表达式) 3. 语句1; 4. else 5. 语句2;
(1)功能:如果表达式的值为真,则执行语句1,否则执行语句2。
(2)if...else...等同条件运算符
注:if()...else...是一个语句,不要想成两个语句了。else字句不能作为语句单独使用,它必须是if语句的一部分,与if配对使用。
3.多分支if语句
1. //多分支if语句 2. if (表达式1) 3. 语句1; 4. else if (表达式2) 5. 语句2; 6. ... 7. else if (表达式n) 8. 语句n; 9. else 10. 语句n+1;
(1) 功能:依次判断表达式的值,当出现一个表达式的值是真时,则执行其对应的语句,然后跳转到整个if语句之后继续执行程序;如果所有表达式均为假,则执行else后的语句,即语句n+1。
(2)else if(表达式)表达式如果是当且仅当只有一个条件时可以省略if
(3)单分支if语句VS多分支if语句:多分支更好,因为单分支if语句,每个都要判断,多分支if语句判断为真就跳到整个if语句之后了。即多分支if语句效率更高。
实践:代码上机如下
//单分支if语句 #include<stdio.h>//预处理,头文件对scanf,printf函数的声明 int main() { unsigned age = 0;//unsigned-关键字-无符号整形 //输入 scanf("%d", &age); if (age >= 18) printf("成年\n"); return 0; }
//双分支if语句 #include<stdio.h> int main() { unsigned age = 0; //输入 scanf("%d", &age); if (age >= 18) printf("成年\n"); else printf("未成年\n"); return 0; }
//多分支if语句 #include<stdio.h> int main() { unsigned age = 0; scanf("%d", &age); if (age < 18) printf("未成年\n"); else if (age >= 18 && age <= 35)//&&-逻辑与操作符-都为真,才真 printf("青年\n"); else if (age > 35 && age < 50) printf("中年\n"); else if (age >= 50 && age < 80) printf("老年\n"); else printf("老寿星\n"); return 0; }
如果条件成立,要怎么执行多条语句?
注意:在if和else后面只能控制一条语句---->要控制多条语句,此时要用花括号“{}”将这几个语句括起来成为一个复合语句(也即代码块,这里的一对 { } 就是一个代码块)。
int main() { if (表达式) { 语句列表1; } else { 语句列表2; } return 0; }
#include<stdio.h> int main() { unsigned age = 0; //输入 scanf("%d", &age); if (age >= 18) printf("成年\n"); printf("谈恋爱\n"); return 0; }
从以上代码,我们就可知if只能控制一条语句
#include<stdio.h> int main() { unsigned age = 0; //输入 scanf("%d", &age); if (age >= 18) { printf("成年\n"); printf("谈恋爱\n"); } return 0; }
如上当我们需要控制多条语句时,我们则应该使用代码块。
2.1.2 if语句的嵌套(悬空else)
当if语句的操作语句中包含其他if语句时,称为嵌套的if语句。
//悬空else #include<stdio.h> int main() { int a = 0; int b = 2; //比较一个变量和一个常量是否相等的时候 //建议把变量放在等号的左边 //因为当只写一个等号,写错时编译器也不报错 if (1 == a) if (2 == b) printf("hehe\n"); else printf("haha\n"); return 0; }
程序输出:不输出(if()...else...是一条语句)
else的配匹:else总是与它前面最近的一个尚未匹配的if相匹配。
补充:当比较一个变量和一个常量是否相等的时候,建议把变量放在等号的左边
改进
//适当的使用{}可以使代码的逻辑更加清楚。 //代码风格很重要 #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; }
2.1.3if书写格式的对比
int main() { int x = 1; int y = 2; //代码一 if (x > y) { return x; } return y; //代码二 if(x>y) { return x; } else { return y; } }
代码二更好,逻辑更加清晰,不容易出错。
2.1.4练习
1. 判断一个数是否为奇数
//1. 判断一个数是否为奇数 #include<stdio.h>//预处理,头文件对scanf printf函数的声明 int main() { int a = 0;//变量先定义,在使用 //输入 scanf("%d", &a);//&-取地址操作符 if (a % 2 != 0)//%-取余 { printf("%d %s\n", a,"奇数"); } else { printf("%d %s\n", a, "不是奇数"); } return 0; }
2. 输出1-100之间的奇数
//2. 输出1-100之间的奇数 #include<stdio.h> int main() { //代码一 //循环先产生1-100的数 //判断数是否是奇数 //是奇数打印 //int i = 0; //while (i <= 100) //{ // if (i % 2 != 0)//判断是否为奇数 // { // printf("%d ", i); // } // i++; //} //printf("\n"); //代码二 //通过思考1-100的奇数,奇数+2=下一个奇数 int i = 1; while (i <= 100) { printf("%d ", i); i += 2; } printf("\n"); return 0; } //代码二更好,效率更高(比一少循环,且不用判断)
运行结果:
总结:
使用if语句的注意事项:
(1)if语句中的“表达式”必须用“()”括起来。“表达式”的值非0为真,0为假。
(2)else字句是if语句的一部分,必须与if配对使用,不能单独使用。
(3)在if和else后面只能控制一条语句---->要控制多条语句,此时要用花括号“{}”将这几个语句括起来成为一个复合语句(也即代码块,这里的一对 { } 就是一个代码块)。
(4)if语句允许嵌套,但不建议嵌套的层数太多(一般为7层(直接套))。为了明确匹配关系,避免匹配错误,建议将内嵌的if语句,一律用代码块括起来
(5)else的配匹:else总是与它前面最近的一个尚未匹配的if相匹配。
2.2 switch语句
switch 语句也是一种分支语句,是多分支选择语句。(if语句只有两个分支可以选择,而实际问题中常常需要用到多分支的选择)
常常用于多分支的情况。
比如:
输入 1 ,输出星期一
输入 2 ,输出星期二
输入 3 ,输出星期三
输入 4 ,输出星期四
输入 5 ,输出星期五
输入 6 ,输出星期六
输入 7 ,输出星期日
当然这些我们可以使用嵌套的if语句来处理,但如果分支较多,则嵌套的if语句层数多,程序冗长且可读性降低。(即太复杂)
那我们就得有不一样的语法形式。
这就是 switch语句。
//switch语句 switch (整形表达式) { case 整形常量表达式1: 语句1; break; ...... default: 语句n; }
注意:
(1)switch后的表达式为整形,如:int、long、short、char(到下面case转成对应的ASCII值)
(2)每一个case的常量表达式的值,必须互不相同,否则就会出现互相矛盾的想象
(3)当表达式的内容与某个case后的常量相等后,就执行该case下的语句,break表示该case以后的内容不会执行,如果没有跟break,会继续执行当前case之后的case分支。
2.2.1 在switch语句中的break
在switch语句中,我们没有办法直接实现分支,搭配break使用才能实现真正的分支。
如下:
//代码一:不搭配break #include<stdio.h> int main() { int day = 0; //输入 scanf("%d", &day); 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; }
//代码二,搭配break #include<stdio.h> int main() { int day = 0; //输入 scanf("%d", &day); 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; }
那是不是我们case后面一定要加break呢?
不是的,我们要根据实际问题选择是否加break。(多个case共用一组执行语句时,共用的执行语句写在最后一个,其余可省略)
如下:
1.
//1. 输入1 - 5,输出的是“工作日”; //2. 输入6 - 7,输出“休息日” #include<stdio.h> int main() { int day = 0; //输入 scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; } return 0; }
(1) 总结:break语句 的实际效果是把语句列表划分为不同的分支部分。
(2)编程好习惯
在最后一个 case 语句的后面加上一条 break 语句。
(之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break 语句)。
2.2.2default子句
如果表达式的与所有的case标签的值都不匹配怎么办?
这个时候结构的所有语句都被跳过,程序并不会终止,也不会报错。
但是,如果你不想忽略不匹配所有标签的表达式的值该怎么办呢?
你可以在语句列表中加一条default子句,default可以写在任意一个case标签可以出现的位置。
1、功能
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个 switch 语句中只能出现一条 default 子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个 case 标签一样执行 default 子句。
2、编程好习惯
(1)在每个 switch 语句中都放一条 default 子句是个好习惯,甚至可以在后边再加一个 break 。
(2)虽然default子句可以凡在任意地方,但建议放在最后(习惯上我们前面处理正确的,后面处理异常的)
如下:
#include<stdio.h> int main() { int day = 0; //输入 scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default: printf("输入错误了\n"); break;//break在最后可省略 } return 0; }
2.2.3练习
#include <stdio.h> int main() { int n = 1; int m = 2; switch (n) { case 1: m++; case 2: n++; case 3: switch (n)//switch允许嵌套使用 { case 1: n++; case 2: m++; n++; break;//跳出本次的switch语句 } case 4: m++; break; default: break; } printf("m=%d n=%d\n", m, n); return 0; }
1、在case后面虽然包含一个以上执行语句,但可以不用代码块,它们会自动顺序执行本case后面所有的执行语句
2、switch可以嵌套使用
3、break跳出本次的switch语句(注:像打游戏一样只能一关一关过,一次只能过一关)