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语句
if(表达式)
语句;
(1)非0为真,0为假
(2)功能:如果表达式的值为真,则执行其后面的语句,否则不执行该语句。
2.双分支if语句
//双分支if语句
if(表达式)
语句1;
else
语句2;
(1)功能:如果表达式的值为真,则执行语句1,否则执行语句2。
(2)if...else...等同条件运算符
注:if()...else...是一个语句,不要想成两个语句了。else字句不能作为语句单独使用,它必须是if语句的一部分,与if配对使用。
3.多分支if语句
//多分支if语句
if (表达式1)
语句1;
else if (表达式2)
语句2;
...
else if (表达式n)
语句n;
else
语句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. 判断一个数是否为奇数
#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语句
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 - 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)编程好习惯
2.2.2default子句
如果表达式的与所有的case标签的值都不匹配怎么办?
这个时候结构的所有语句都被跳过,程序并不会终止,也不会报错。
但是,如果你不想忽略不匹配所有标签的表达式的值该怎么办呢?
你可以在语句列表中加一条default子句,default可以写在任意一个case标签可以出现的位置。
#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语句(注:像打游戏一样只能一关一关过,一次只能过一关)