if 条件判断


为了应付程序可能遇到的各种状况,C 提供了if条件判断陈述,它的语法如下:

if (条件式) 
    语句一; 
else 
    语句二;

这个语法的意思,白话来说,就是当条件式成立时(真),则执行语句一,要不然就执行语句二;如果条件式不成立时并不想作任何事,则else可以 省略。

if后如果有两个以上语句,称之为复合语句(compound statement),此时你必须使用{}将复合语句包括起来,例如:

if (条件式) { 
    语句一; 
    语句二; 
} 
else { 
    语句三; 
    语句四; 
}

ifelse中只有一个语句的时候,可以不写{},不过,现在鼓励也是加上{},这有助于可读性,也有助于避免缩排上造成的代码阅读误解。

下面来写个简单的程序,判断使用者的输入是奇数还是偶数:

#include <stdio.h>

int main(void) {
    int input = 0;
    int remain = 0;

    printf("输入整数:");
    scanf("%d", &input);

    remain = input % 2;
    if(remain == 1) {
        printf("%d 为奇数\n", input);
    }
    else {
        printf("%d 为偶数\n", input);
    }

    return 0;
}

执行结果:

输入整数:10
10 为偶数

这个程序很简单,使用余数运算来计算除以2后的余数,偶数的余数会是 0,而奇数会是 1,由此判断输入为奇数还是偶数;事实上如果 C 了解非 0 值在判断式中表示真,0 值表示假的意义的话,这个程序也可以这么写:

#include <stdio.h>

int main(void) {
    int input = 0;

    printf("输入整数:");
    scanf("%d", &input);

    if(input % 2) {
        printf("%d 为奇数\n", input);
    }
    else {
        printf("%d 为偶数\n", input);
    }

    return 0;
}

if中也可以再设定执行的条件,例如:

if (条件式一) { 
    语句一; 

    if(条件式二) {
        语句二; 
    }

    语句三; 
}

这只个简单的例子,其中语句二要执行,必须同时满足条件式一与二才行;再来看个例子:

if (条件式一) { 
    语句一; 
    // 其他语句 
} 
else {
    if(条件式二) { 
        语句二;
    }
}

如果条件式一不满足,就会执行else中的陈述,而你在这边进行条件式二的测试,如果满足就执行条件式二,由於单行陈述可以省略{},而且 C 是个自由格式语言,可以适当地排列这个程序,这会比较好懂一些:

if (条件式一) { 
    语句一; 
    // 其他语句 
} 
else if(条件式二) { 
    语句二;
}

基于这个方式,可以如下设定多个条件,且易读易懂:

if (条件式一) { 
    陈述一; 
} else if(条件式二) { 
    语句二; 
} else if(条件式三) { 
    语句三; 
} else { 
    语句四;
}

语句四会在条件式一、二、三都不成立时执行;下面这个程序是个简单的例子,处理学生的成绩等级问题:

#include <stdio.h>

int main(void) {
    int score = 0;

    printf("输入分数:");
    scanf("%d", &score);

    if(score >= 90) {
        puts("得 A");
    } else if(score >= 80 && score < 90) {
        puts("得 B");
    } else if(score >= 70 && score < 80) {
        puts("得 C");
    } else if(score >= 60 && score < 70) {
        puts("得 D");
    } else {
        puts("得 E(不及格)");
    }

    return 0;
}

执行结果:

输入分数:60
得 D

在这边要注意的是,ifelse是就最近的一组来配对,例如下面这个程序依缩排来看,有什么问题吗?

if (条件式一) 
    if(条件式二) 
        语句一; 
else 
    语句二;

很多人都会以为条件式一的if会与else配对,但事实上是条件式二的ifelse配对,加上括号的话就可以一目了然了:

if (条件式一) { 
    if(条件式二) {
        语句一; 
    } else { 
        语句二;
    } 
}

如果想避免这种错误,在程序中多使用括号是必要的,多写一些总是比少写一些来得保险一点。

如果想避免这种错误,在程序中多使用括号是必要的,多写一些总是比少写一些来得保险一点。

Apple 曾经提交一个 iOS 上的安全更新,原因是在某个函数中有两个连续的缩排:

...       
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;
...

因为缩排在同一层,阅读代码时开发者也就没注意到,又没有用{}定义区块,结果就是goto fail无论如何都会被执行到的错误。


展开阅读全文