判断结构类似Excel中的IF函数,用于去根据条件表达式为真时需要执行的语句(必需的)和条件为假时要执行的语句(可选的)。
逻辑真假值
在 C 中,把任何非零和非空的值假定为 true,把零或 null 假定为 false。在C99 以前的没有提供布尔变量,一般 int 变量来表示布尔变量,一切不等0的值都表示为真,0表示假,也就是非零即真。
if
if 语句是 C 中最为常见的判断语句。比如我们需要判断一个数字是否是正数,如下例:
#include<stdio.h>
int main() {
int a = -10;
if(a > 0) {
printf("%d is positive number.", a);
}
return 0;
}
执行结果:
10 is positive number.
若要求程序既能判断变量是正数,也能判断变量是负数,可以在 if 语句后补充一个 else,如下例:
#include<stdio.h>
int main() {
int a = -10;
if(a > 0) {
printf("%d is positive number.", a);
} else {
printf("%d is negative number.", a);
}
return 0;
}
执行结果:
-10 is negative number.
如果要求还能判断数字是否为零,可以在 if 和 else 中间增加一个 else if 的结构,如下例:
#include<stdio.h>
int main() {
int a = 0;
if(a > 0) {
printf("%d is positive number.", a);
} else if(a == 0) {
printf("number is zero.");
} else {
printf("%d is negative number.", a);
}
return 0;
}
执行结果:
number is zero.
三元运算符 ?:
就是一种判断结构,结合它可以将上例调整成这样:
int a = 10;
if(a == 0) {
printf("number is zero.");
} else {
printf("%d is %s number.", a, a > 0 ? "positive" : "negative");
}
当然,为了程序的可读性,不建议这样做!
switch
一个 switch 语句允许测试一个变量匹配某个值或多个值时的情况,每个值称为一个 case,每次测试完成后,在分支后的 break 表示测试结束。
例如,设定分数的取值范围在 0 ~ 100之间,现为分数划分等级, [90, 100] 区间内为 A,[80, 90) 区间内为 B,[60, 80) 区间内为 C,[0, 60) 为 D。那么要求,输入一个分数后,根据分数得到对应成绩的等级,并显示不同的文字提示。
#include<stdio.h>
int main() {
int score;
char grade;
printf("input your score:");
scanf("%d", &score);
if(score >= 0 && score <= 100) {
if(score >= 90) {
grade = 'A';
} else if(score >= 80) {
grade = 'B';
} else if(score >= 60) {
grade = 'C';
} else {
grade = 'D';
}
} else {
grade = 'E';
}
if(grade != 'E') {
printf("grade is %c. ", grade);
}
switch(grade) {
case 'A': printf("legendary!"); break;
case 'B': printf("perfect!"); break;
case 'C': printf("good!"); break;
case 'D': printf("come on!"); break;
default: printf("is not a legal score!"); break;
}
return 0;
}
执行程序,当我们输入 96 的时候,得到结果:
input your score:96
grade is A. perfect!
当输入的不是 [0, 100] 区间内的整数时,就会提示 is not a legal score!
:
input your score:120
is not a legal score!
当然,该程序可以不需要 switch ,使用 if 也可以完成。但是不难发现,switch 和 if 两种分支结构在进行逻辑运算的时候是不一样的。switch 是测试变量是否与某个或某些字面量是相等的,而 if 语句的 ()
中可以编写不仅仅是等值逻辑表达式还能进行更加复杂的逻辑运算的其它逻辑表达式。从这个角度讲,switch 貌似比 if 在做判断的时候更加迅速。在使用场景上,基本上所有的 switch 结构都能被调整为 if 结构。一般地,switch 适用于比对可枚举的字面量。故而,若某个场景能够在 if 和 switch 上做选择的话,建议使用 switch。
使用 switch 需要注意的是:
- default 子句不是必须的,它是当 switch 的所有的 case 都匹配失败的时候执行的子句。例如:
if(grade != 'E') {
printf("grade is %c. ", grade);
} else {
printf("is not a legal score!");
}
switch(grade) {
case 'A': printf("legendary!"); break;
case 'B': printf("perfect!"); break;
case 'C': printf("good!"); break;
case 'D': printf("come on!"); break;
}
- 每个 case 都应该存在一个 break 来结束 case,否则会出现 case 子句贯穿的现象。例如将上例中的
case 'A'
子句中的 break 去掉的话,结果是,当匹配到等级 B 的时候不仅输出了等级 B 该输出的内容,同时也输出了等级 A 该出现的内容,如下所示:
grade is A. legendary!perfect!
- switch 分支不像 if 分支那样拥有独立的作用域,故而,同名标识符在不同的 case 分支中声明是不允许的。例如:
switch(grade) {
case 'A':
printf("legendary!");int i = 10;
break;
case 'B':
printf("perfect!"); int i = 10;
break;
case 'C': printf("good!"); break;
case 'D': printf("come on!"); break;
default: printf("is not a legal score!"); break;
}
在编译的时候,程序会提示错误:
error: redefinition of 'i'
note: previous definition of 'i' was here
如果有必要一定要这样做,可以手动增加 {}
以限制变量的作用域。例如:
switch(grade) {
case 'A':
{printf("legendary!");int i = 10;}
break;
case 'B':
{printf("perfect!"); int i = 10;}
break;
case 'C': printf("good!"); break;
case 'D': printf("come on!"); break;
default: printf("is not a legal score!"); break;
}
- 如果多个 case 需要走相同的逻辑处理,建议的写法是:
case 'A':
case 'B':
// to do something here...
break;
而不是
case 'A':
// to do something here...
case 'B':
// to do something here...
break;