【C语言-15】条件语句,快速学会if/else

【C语言-15】条件语句,快速学会if/else

1. 控制流

一个完整的程序控制流包含下面三种控制流:

  1. 顺序流程
  2. 分支流程
  3. 循环流程

我们之前看过的程序都是顺序流程的。顺序流程至上而下,依次执行。

现在有一个需求:
要求我们输入一个整数。如果这个数值在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 (210之间)
        输出In
        if(大于10)
            输出Right
}

事实上,我们可以发现大于10这个分支可以省略掉。由于测试条件是互斥的,如果一个数值即不小于2,又不在2到10之间,那么它必然大于10。

if (小于2)
    输出Left
    if (210之间)
        输出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';