C语言深入讲解语句与选择结构的使用
知识点1-语句
1.1 语句
1.表达式语句
由一个表达式加分号构成一个表达式语句,其一般形式如下:
表达式 ;
Q1:什么是表达式?
A1:表达式就是C语言中由运算符和数据构成的式子;表达式运算的结果称为表达式的值,以下都是一些常见的表达式。
//表达式
1
-5
4+20
x = q++ % 3
a*(b + c/d)/20
q > 3
kiko:因此表达式语句就是在上面这些表达式后面加一个分号就完事了~
//表达式语句
1;
-5;
4+20;
x = q++ % 3 ;
a*(b + c/d)/20 ;
q > 3;
2.控制语句
由名字可见,控制语句用于控制程序的执行过程,它是由特定的语句定义的,我个人将C语言中的控制语句分为以下3类:
- 选择语句:if-else语句、switch-case语句。
- 循环语句:while语句、do-while语句、break语句。
- 跳转语句:break语句、goto语句、continue语句。
本期我们就讲三类语句中的第一类,也就是选择语句!
3.空语句
空语句是只有一个分号的语句,它在程序中什么也不做,可能就是起到一个占位作用。
; //空语句
for( int i=0; i<10; i++ )
; //循环体为空
4.复合语句
可以用花括号{ }将一系列语句括起来,使其大功能上相当于一条语句,这就是语句块。语句块中可以有变量声明,声明必须位于块的开始。
int x; int y; x = 6; { int z = 100; y = z/x; printf("%d \n", y); } //从大功能上看,{}里面的三条语句相当于一条语句
知识点2-选择结构
2.1 if语句
Q1:什么是if语句?
A1:if语句提供一种二分支选择的控制流程,它根据表达式的值来决定执行两个不同情况下的其中一个分支程序段。
1.if语句的单分支
单分支就是只有一个分支,当给定的条件满足时,执行一个语句1;当条件不满足时,不进行任何操作,因此只有语句1一种输出,因此我称之为单分支。
if(表达式)
语句1;//如果为真,执行语句;否则不执行
//C语言规定:0为假,非0为真
案例1:如果小于18岁,输出未成年。
//该情况只有一个分支,即只有小于18这种情况输出。 #include<stdio.h> int main() { int age=10; if(age<18) printf("未成年\n"); return 0; }
2.if语句的双分支
双分支就是有两个分支,当给定的条件满足时,执行语句1;当条件不满足时,执行语句2。因此有2种不同的输出,称之为双分支。
if(表达式)
语句1;//表达式为真,执行语句1
else
语句2;//否则,执行语句2
案例2:小于18打印未成年;否则打印成年。
//该情况只有两个分支,即只有未成年、成年两种不同的输出结果 #include<stdio.h> int main() { int age=20; if(age<18)//年龄小于18时打印未成年 printf("未成年\n"); else//否则打印成年 printf("成年\n"); return 0; }//由于我们将age初始化为20,因此最终会选择打印“成年”
3.if语句的多分支
多分支就是有多个分支,这边使用else if来使得if语句也可以进行多个分支的判断,我们在程序中只要通过增加else if,就可以增加if语句判断的分支数。
如下例中,当表达式1满足执行语句1;如果不满足表达式1,满足表达式2,执行语句2;其余情况执行语句3,有3种不同的分支,因此我们称之为多分支。
if(表达式1)//表达式1为真,执行语句1
语句1;
else if(表达式2)//表达式1为假,表达式2为真,执行语句2
语句2;
else//其余所有情况,执行语句3
语句3;
案例3:输入年龄后,判断一个人的年龄范围并输出其结果(共有5种可能:未成年、青年、壮年、老年、老不死)
//有5种不同的输出,因此判断为多分支,需要结合else if #include<stdio.h> int main() { int age=0; scanf("%d",&age); if(age<18) printf("未成年\n"); else if (18<=age && age<28) printf("青年\n"); else if(age>=50 && age<50) printf("壮年\n"); else if(age>=50 && age<90) printf("老年\n"); else//最后一个else也可以省略 printf("老不死"); return 0; }
4.if语句与代码块
如果条件成立,要执行多条语句,应该使用代码块{ }。
#include <stdio.h>
int main()
{
if(表达式)
{
语句列表1;//包含多条语句
}
else
{
语句列表2;//包含多条语句
}
return 0;
}
案例4:输入年龄后,判断一个人的年龄范围并输出其结果(共有5种可能:未成年、青年、壮年、老年、老不死)
#include<stdio.h> int main() { int age=10; if(age<18) //情况A(包含多条代码,使用代码块) { printf("未成年\n"); printf("不能谈恋爱\n"); }//一对大括号,就是一个代码块 else //情况B(包含多条代码,使用代码块) { if (18<=age && age<28) printf("青年\n"); else if(age>=50 && age<50) printf("壮年\n"); else if(age>=50 && age<90) printf("老年\n"); else//最后一个else也可以省略 printf("老顽童"); } return 0; }
5.悬空else
Q1:什么是悬空else?
A1:else是和它离的最近的if匹配的,我们可以看一看下面这道例题来深入了解。
#include<stdio.h> int main() { int a=0; int b=2; if(a==1) if(b==1) printf("hehe\n"); else printf("haha\n"); return 0; }
从程序的书写形式上来看,if (a==1)
与 else printf("haha\n");
是匹配的,按这个逻辑,因为a=0不满足第一个if条件,因此会直接进入else printf("haha\n");
,本题最终应当输出haha,可真的如此吗?
结果居然是什么都没有输出。这是因为else是和离它最近if相匹配的,也就是与if(b==1)相匹配,因此上图橙色方框圈起来的这几行代码都属于if (a==1) 条件满足的情况,而本题a初始化为0,不满足a==1,因此就不会有任何输出。
2.2switch语句
1.switch语句的定义
Q1:什么是switch语句?
A1:switch语句是一种专门进行多分支选择的分支控制语句。上面介绍了if语句使用else if可以实现多分支,但是具体实现起来程序冗长且难以理解,而采用switch语句实现分支则结构更清晰。switch语句的一般语法结构如下:
switch(表达式)
{
case 常量表达式1:语句1;(break;)
case 常量表达式2:语句2;(break;)
···
case 常量表达式n:语句n;(break;)
default:语句n+1;
}
switch语句的执行过程:
- 计算switch表达式的值。
- 将该值与case后面的常量表达式的值相比较,当switch表达式的值与某个常量表达式i的值一致时,就从该case后的语句i开始执行,直到遇到break语句或整个switch结束。
- 若switch表达式与任何常量表达式的值均不同时,则执行default后面的语句或执行switch结构的后续语句。
上述switch结构的几点注意:
(1)switch 后面的圆括号内的表达式类型一般为整型、字符型和枚举型,不能为浮点型。
(2)case标签: case后必须跟整数类型(包括char类型)的常量或整型常量表达式。
Q2:case后为什么可以跟char类型?
A2:因为ASCII字符在内存中是以整型存储的!
(3)break语句:它使程序控制跳出当前循环或switch语句的剩余部分,它实际效果是把语句列表划分为不同的分支部分。
(4)default子句:当 switch表达式的值并不匹配所有case标签的值时,这个default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。
2.switch语句的实战案例
案例1.0 选择打印星期
//该程序在接收到整数1-7后,会打印相对应星期,然后运行到break,跳出switch语句 #include<stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day)//day必须定义为整型 { case 1+0 :printf("星期1\n");break;//case1+0 √ case后跟整型常量就行 case 2:printf("星期2\n");break; case 3:printf("星期3\n");break; case 4:printf("星期4\n");break; case 5:printf("星期5\n");break; case 6:printf("星期6\n");break; case 7:printf("星期7\n");break; } return 0; }
案例1.1 改进打印星期
题目变化:输入1-5打印工作日;输入6-7打印休息日.
巧妙利用case语句未遇到break程序会持续进行,因此无论从case1进入还是从case5进入,最终都会在printf("工作日")下一行的break结束switch语句;case6&case7同理。
案例2.0:求求看最后m与n的值为多少?
#include<stdio.h> 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++; default: break; } printf("m=%d , n=%d \n", m, n); return 0; }
这一题的细节主要在于理解switch的嵌套,我们一步一步分析:
- 进入case1,m++,m变为3。
- 进入case2,n++,n变为2。
- 进入case3,这里嵌套了一个子switch语句,由于此时n为2,因此进入子case2,m++,n++,遇到break跳出子switch语句,此时m为4,n为3。
- 进入case4,m++,m变为5,由于没有遇到break继续向下执行。
- 遇到default中的break,结束switch语句,打印结果,此时m=5,n=3。