if 语句
if 语句是 C 语言中最基本的选择结构,根据条件的真假决定执行哪条(或哪些)语句。C 语言将任何非零值视为"真",零视为"假",这让条件表达式非常灵活,但也需要小心处理赋值与比较的混淆。
基本语法
if (表达式)
语句
if (表达式) {
语句1;
语句2;
}
int score = 85;
if (score >= 60)
printf("Passed\n");
if (score >= 90) {
printf("Excellent!\n");
printf("Grade: A\n");
}
if-else
else 分支在条件为假时执行:
if (score >= 60)
printf("Passed\n");
else
printf("Failed\n");
多分支判断:
if (score >= 90)
printf("A\n");
else if (score >= 80)
printf("B\n");
else if (score >= 70)
printf("C\n");
else if (score >= 60)
printf("D\n");
else
printf("F\n");
else if 是 else 后面紧跟一个 if 的简写,不是独立的语法。上面的代码等价于:
if (score >= 90)
printf("A\n");
else {
if (score >= 80)
printf("B\n");
else {
if (score >= 70)
printf("C\n");
/* ... */
}
}
条件的真假
C 语言中,任何标量表达式都可以作为条件:
/* 整数:非零为真,零为假 */
int count = 5;
if (count) /* 真 */
printf("Has items\n");
/* 指针:非 NULL 为真 */
int *ptr = malloc(sizeof(int));
if (ptr) /* 真 */
*ptr = 10;
/* 比较结果 */
if (x == 5) /* 等于 */
if (x != 0) /* 不等于 */
if (x > 0 && x < 100) /* 范围判断 */
/* 函数返回值 */
if (scanf("%d", &n) == 1) /* 成功读取一个整数 */
process(n);
/* 赋值后判断 */
if ((c = getchar()) != EOF) /* 读取并判断是否到文件尾 */
process_char(c);
悬空 else 问题
else 总是与最近的未匹配的 if 配对:
if (x > 0)
if (y > 0)
printf("Both positive\n");
else /* 与内层 if 配对 */
printf("x > 0 but y <= 0\n");
如果意图是让 else 与外层 if 配对,必须用花括号:
if (x > 0) {
if (y > 0)
printf("Both positive\n");
} else { /* 与外层 if 配对 */
printf("x <= 0\n");
}
始终使用花括号可以完全避免悬空 else 问题。
常见错误
赋值与比较混淆:
if (x = 5) /* 将 5 赋给 x,表达式值为 5(真) */
printf("Always true\n");
if (x == 5) /* 比较 x 是否等于 5 */
printf("Maybe true\n");
防御性写法:将常量放在左边:
if (5 == x) /* 如果误写成 =,编译器报错 */
/* ... */
编译器警告(-Wall)可以捕获大部分这类问题。
多余的分号:
if (x > 0); /* 空语句!if 体为空 */
printf("Positive\n"); /* 这行总是执行 */
/* 正确 */
if (x > 0) {
printf("Positive\n");
}
浮点数直接判等:
double x = 0.1 + 0.2;
if (x == 0.3) /* 可能为假! */
printf("Equal\n");
/* 正确 */
#include <math.h>
if (fabs(x - 0.3) < 1e-9)
printf("Approximately equal\n");
条件表达式 vs if-else
简单的二选一可以用条件运算符 ?::
/* if-else */
int max;
if (a > b)
max = a;
else
max = b;
/* 条件运算符 */
int max = (a > b) ? a : b;
条件运算符是表达式,可以嵌入到其他表达式中;if-else 是语句,更灵活但稍冗长。对于简单的赋值,条件运算符更简洁;涉及副作用或多分支时,if-else 更清晰。
最佳实践
- 始终使用花括号,即使只有一条语句
- 将常量放在比较的左边(防御性编程)
- 避免深层嵌套的
if,超过 3 层考虑重构 - 浮点数比较使用误差范围
- 复杂的条件用括号明确优先级
if-else if-else链考虑是否更适合switch