分支控制:if 语句
if 语句
控制流语句允许我们根据条件来选择程序执行路径,这也被称为分支语句或选择语句。其中if语句是最常用的一种,形式如下:
if (表达式)
语句
如果表达式求值为真,就执行语句;否则,跳过该语句,向下执行。
if (1 < 2) // 1<2 为true
printf("1<2\n"); // 打印 1<2
printf("here"); // if语句结束,打印 here
if (1 > 2) // 1>2 为false
printf("1>2\n"); // 跳过不执行
printf("here"); // if语句结束,打印 here
在下面的示例中,要注意是,空字符串""求值也为真!
#include <stdio.h>
int main()
{
char a = 'a';
char b = 'b';
if (3 > 2)
printf("3 > 2\n");
if (a < b)
printf("a < b\n");
if (1 && -1)
printf("1 && -1\n");
if ("hello")
printf("hello\n");
if ("")
printf("empty string\n");
if ((a == b) || 1)
printf("(a == b) || 1\n");
if (0)
printf("0\n");
return 0;
}

复合语句
复合语句是使用一对花括号"{}"组织起来的单条或多条语句的集合;也被称为语句块或代码块。复合语句在文法上相当于单条语句,这表示if的语句部分可以是复合语句,很多时候,使用复合语句使得我们的意图能被正确表达。下面的程序中,我们希望当swap为真时,交换a、b的值,代码在编排上的意图很明显,但是却不能达成目标。
int a = 1, b = 2;
int temp = -1;
if (swap)
temp = a;
a = b;
b = temp;
语句temp = a;构成了if的唯一语句,之后的语句不管if成立与否都会执行,这可以通过使用复合语句解决。
if (swap)
{
temp = a;
a = b;
b = temp;
}
示例中我们将if语句部分缩进了一些字符(4个空格);下面未缩进的代码依然是正确的,但代码缩进后的排版使得程序的可读性更好。
if (true)
printf("true");
if (1)
{
printf("happy!");
printf("happy!");
}
if-else 语句
if 语句仅提供了在表达式为真时的逻辑处理,为了处理条件不成立的情形,可以通过 if-else 语句实现。
if (表达式)
语句1
else
语句2
语句执行时,先计算表达式的值,为真则执行语句1;否则执行语句2。
if (2 > 3) // 表达式求值为假
printf("2 > 3\n"); // 语句1不执行
else
printf("2 < 3\n"); // 执行语句2
在语法上,else关键字之前只能有一条语句,下面的代码在语法上导致else不能与if匹配,造成错误。
if (true)
printf("true");
printf("woo....");
else
printf("false");
这时可以使用复合语句来表达正确的含义,记得,复合语句在语法上等价于单条语句。
if (true)
{
printf("true");
printf("woo....");
}
else
{
printf("false");
}
这里,else分支中只有一条语句,花括号不是必须的,但加上之后,使得对应关系更明确。
else-if 语句
if-else 语句表达了真与假两种状态的分支处理,一些情况下可能有一系列相关的状态需要分支处理,这可以通过为if语句增加else-if子句来实现。
if (表达式)
语句
else if (表达式)
语句
else if (表达式)
语句
else
语句
这种if语句序列是编写多路判定的常用方法。其中的各表达式将被依次求值,一旦某个表达式结构为真,则执行与之关联的语句,并终止整个语句序列的执行。最后一个else部分用于处理“上述条件均不成立”的情况或默认情况,也就是当上面各条件都不满足时的情形。有时候并不需要针对默认情况执行显示的操作,这种情况下,else子句部分可以省略。
下面的程序,使用多路判定的方式,将考试成绩转换为对应的等级:成绩74分,匹配了else if (score >= 70 && score < 80)部分,因此打印出了等级"C",然后整个if语句结束,程序流向return 0;语句处。
#include <stdio.h>
int main()
{
int score = 74;
printf("score: %d ==> grade: ", score);
if (score >= 90 && score <= 100)
printf("A");
else if (score >= 80 && score < 90)
printf("B");
else if (score >= 70 && score < 80)
printf("C");
else if (score >= 60 && score < 70)
printf("D");
else
printf("E");
return 0;
}

if 语句嵌套
如果认为if语句是基石,那么if-else语句、else-if语句都是对它的扩展,我们将它们统称为if语句。if语句自身就是一个语句,所以if语句的语句部分可以是if语句,读起来有些拗口,但实则很简单。图中带星号的语句扩展为一个级联if或if-else语句。
if (表达式) if (表达式) if (表达式)
*语句 =====扩展=====>if (表达式) if (表达式)
*****语句==========扩展=========>*if (表达式)
*****语句
*else
*****语句
当if语句嵌套 if-else 子句后,else总是与最近的if相匹配。在下面的代码中,我对if与else做了编号并连线,#3与最近的if配对;#2则与第2个if配对;#1并没有与之配对的else语句。
if (1) // #1
if (2) // #2-----------+
if (3) // #3----+ |
printf("3"); | |
else // #3----+ |
printf("else-3"); |
else // #2-----------+
printf("else-?")
这里故意让#2的else部分#1的if对齐,但在程序的执行路径上,它们并不匹配。对于这种嵌套的if语句,良好的编码实践就是使用缩进与花括号,清晰的表达我们的意图。
if (1)
{
if (2)
{
if (3)
printf("3");
else
printf("else-3")
}
else
{
printf("else-2");
}
}
练习
1 编写if语句使它成立,但语句部分什么都不做。
2 编写一个根据游戏玩家等级而随机产生不同怪物数量的模拟程序。
3 编写一个嵌套if语句。