【C语言-15】条件语句,快速学会if/else
1. 控制流
一个完整的程序控制流包含下面三种控制流:
- 顺序流程
- 分支流程
- 循环流程
我们之前看过的程序都是顺序流程的。顺序流程至上而下,依次执行。
现在有一个需求:
要求我们输入一个整数。如果这个数值在2到10之间,那么输出yes,否则什么都不做。
让我们考虑一下,这个流程属于三种流程中的哪一种呢?
这个需求中出现了一个测试条件:2到10之间。如果满足条件则走向一个流程,否则就走向另一个流程。
这种情况,程序之中出现了岔路口,那么这个流程应该是属于分支流程。
2. C语言中的分支流程
if (测试条件)
条件为真的流程
我们把输入的整数的变量命名为x,那么x应该满足条件
2<=x<=10
。将条件填入if语句中测试条件的括号内。
if (2<=x<=10)
printf("yes\n");
我们这样写条件对了吗?
在运算符那里已经讨论过了,这样的写法是不正确的。
例如,x的值为1。子表达式
2 <= 1
为假,即表达式结果为0。
C语言中在计算表达式结果时,会使用0表示假,1表示真。
接着计算表达式,
0 <= 10
。条件满足,表达式结果为1。if的测试条件结果为1,即真。那么它将输出yes。
很显然,条件被写错了。我们的本意是要让子表达式
2 <= x
与
x <= 10
同时成立。因此,需要在两个表达式中间加上逻辑运算符与&&。
if (2<=x && x<=10)
printf("yes\n");
当x为0时,子表达式
2 <= 0
为假,子表达式
0 <= 10
为真。整个表达式为假。 当x为5时,子表达式
2 <= 5
为真,子表达式
5 <= 10
为真。整个表达式为真。
完整代码如下:
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10)
printf("Yes\n");
return 0;
}
3. else关键词
现在我们将需求修改一下:
要求我们输入一个整数。如果这个数值在2到10之间,那么输出yes,否则输出no。
我们将代码修改如下:
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10)
printf("Yes\n");
printf("No\n");
return 0;
}
我们再后面加上了一行语句,用于输出no。但是这样有个问题,无论测试条件是否满足,都会输出no。我们只想要在测试条件不满足的时候输出no。应该怎样修改呢?
这时候就需要else关键词了。
if (测试条件)
条件为真的流程
条件为假的流程
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10)
printf("Yes\n");
printf("No\n");
return 0;
}
4. 复合语句
if和else关键词只对它后面一条语句产生效果,并且if和else之间仅允许有一条语句 。
如果我们将printf一次打印一个字符,那么if以及else将和它后面第一条语句配对。
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10)
printf("Y");
printf("e");
printf("s");
printf("\n");
printf("N");
printf("o");
printf("\n");
return 0;
}
这时将变成如下的奇怪流程,且由于if与else之间有多条语句,而无法编译成功。
if (测试条件)
条件为真的流程
printf("E");
printf("S");
printf("\n");
条件为假的流程
printf("O");
如果要使用多条语句,我们需要使用花括号将其包含起来,让它们组成 复合语句 。
if (测试条件)
条件为真的流程1
条件为真的流程2
条件为假的流程1
条件为假的流程2
}
我们将代码修改如下:
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10)
printf("Y");
printf("e");
printf("s");
printf("\n");
printf("N");
printf("o");
printf("\n");
return 0;
}
5. 请不要在if或else后面加分号
初学者很容易出现的一个问题,就是认为if的测试条件或else也要以分号结尾。
如下面所示的,在if和else后都加了分号。
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (2<=x && x<=10); // 这里加了分号
printf("Yes\n");
else; // 这里加了分号
printf("No\n");
return 0;
}
if与else将会对其后第一条语句产生影响,而单纯的一个分号将构成空语句。 这时将变成如下的奇怪流程,且无法编译成功。
if (测试条件)
条件为真的流程(空语句)
printf("Yes");
条件为假的流程(空语句)
printf("No");
6. 嵌套if
我们再修改一下需求:
要求我们输入一个整数。如果这个数值小于2,则输出Left。如果数值在2到10之间,则输出In。如果数值大于10,则输出Right。
x < 2, 输出Left 2 <= x <= 10,输出In。 x > 10,输出Right。
我们观察一下流程图,第一个分支流程中,嵌套了另外的分支流程。
if (小于2)
输出Left
if (2到10之间)
输出In
if(大于10)
输出Right
}
事实上,我们可以发现大于10这个分支可以省略掉。由于测试条件是互斥的,如果一个数值即不小于2,又不在2到10之间,那么它必然大于10。
if (小于2)
输出Left
if (2到10之间)
输出In
输出Right
}
完整代码如下:
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (x < 2)
printf("Left\n");
if (2<=x && x<=10)
printf("In\n");
printf("Right\n");
return 0;
}
7. 避免无效的流程
我们考虑一下将程序写成下面这样可以吗?
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (x < 2)
printf("Left\n");
if (2<=x && x<=10)
printf("In\n");
if (x > 10)
printf("Right\n");
return 0;
}
这样虽然结果上没有问题。但是,在最坏情况下,x满足小于2的条件,并完成了输出。那么程序没必要在继续测试后面的条件了。 由于我们的测试条件具有互斥性 ,只要一个测试条件中满足了,就可以输出并结束了。
8. 省略花括号
红框中为一个完整的if结构,虽然这个if语句由复合语句构成,但是整个if结构仍然被看做一条语句。我们可以省略包括它的一对花括号,将代码写成如下形式。else后面直接跟一条if语句。
#include <stdio.h>
int main()
int x;
scanf("%d", &x);
if (x < 2)
printf("Left\n");
else if (2<=x && x<=10)
printf("In\n");
printf("Right\n");
return 0;
}
接下来,我们再看一个更复杂的例子。这个例子里面将有更多的分支。
输入一个学生的分数x。 x < 60,输出不及格。 60 <= x < 70,输出及格。 70 <= x < 80,输出一般。 80 <= x < 90,输出良好。 90 <= x <= 100,输出优秀。
if (x < 60)
printf("不及格"\n);
if (x >= 60 && x < 70)
printf("及格"\n);
if (x >= 70 && x < 80)
printf("一般"\n);
if (x >= 80 && x < 90)
printf("良好"\n);
printf("优秀"\n);
}
上面代码中的嵌套层次较多,花括号层层叠叠,不易理解。 这时,就可以体现省略嵌套花括号的if else形式的优势了。 我们可以将代码简化成如下形式:
if (x < 60)
printf("不及格"\n);
else if (x >= 60 && x < 70)
printf("及格"\n);
else if (x >= 70 && x < 80)
printf("一般"\n);
else if (x >= 80 && x < 90)
printf("良好"\n);
printf("优秀"\n);
}
是不是更加清晰明了了呢?
9. 条件运算符
C语言中提供 条件表达式 作为if else语句的一种便捷形式。
char x, c;
if (x >= 10)
c = 'Y';