一、本节学习定位
本节内容属于流程控制中的重点问题,主要讲解if 语句后误加分号导致逻辑错误的现象。
流程控制是 C 语言学习中的核心内容。只有理解程序的执行流程,才能看懂程序、调试程序,并进一步学习循环、函数、数组和指针等内容。
本节重点包括:
理解if 语句的基本执行逻辑;
理解空语句的含义;
掌握
if (条件);这种写法为什么通常是错误的;区分语法错误、编译警告和逻辑错误;
能够在 VSCode 中编写、编译并验证本节示例程序。
二、if 语句的基本作用
if 语句用于实现选择结构,即根据条件是否成立决定是否执行某条语句。
基本形式如下:
if (表达式) 语句;其执行过程为:
先计算括号中的表达式;
如果表达式的值为真,即非
0,则执行if后面的语句;如果表达式的值为假,即
0,则跳过if后面的语句;程序继续执行后续代码。
例如:
if (3 > 2) printf("AAA\n"); printf("BBB\n");在该程序中,3 > 2成立,因此会执行:
printf("AAA\n");后面的:
printf("BBB\n");并不属于if控制范围,因此无论条件是否成立都会执行。
三、正确示例:if 控制一条语句
1. 示例程序
#include <stdio.h> int main(void) { if (3 > 2) printf("AAA\n"); printf("BBB\n"); return 0; }2. 执行结果
AAA BBB3. 程序分析
| 代码 | 是否受 if 控制 | 执行情况 |
|---|---|---|
printf("AAA\n"); | 是 | 3 > 2成立,所以执行 |
printf("BBB\n"); | 否 | 无论条件是否成立都会执行 |
该程序等价于:
#include <stdio.h> int main(void) { if (3 > 2) { printf("AAA\n"); } printf("BBB\n"); return 0; }花括号虽然不是必须的,但加上花括号后,程序结构更加清晰。
四、条件不成立时的执行结果
1. 示例程序
#include <stdio.h> int main(void) { if (1 > 2) printf("AAA\n"); printf("BBB\n"); return 0; }2. 执行结果
BBB3. 程序分析
1 > 2不成立,因此if后面的语句不会执行:
printf("AAA\n");但下面这条语句不属于if控制范围:
printf("BBB\n");所以最终仍然会输出BBB。
五、常见错误:if 条件后误加分号
1. 错误写法
if (3 > 2); printf("AAA\n"); printf("BBB\n");很多初学者容易在if条件后面误加分号:
if (3 > 2);这段代码通常不会造成语法错误,但会造成逻辑错误。
六、空语句的含义
在 C 语言中,单独一个分号可以构成一条语句:
;这条语句称为空语句。它什么也不做,但在语法上是一条合法语句。
因此:
if (3 > 2);等价于:
if (3 > 2) ;也就是:
if (3 > 2) { // 什么也不做 }这里if控制的并不是后面的printf,而是一个空语句。
七、错误程序的完整执行过程
1. 示例程序
#include <stdio.h> int main(void) { if (3 > 2); printf("AAA\n"); printf("BBB\n"); return 0; }2. 实际等价形式
上面的程序在逻辑上等价于:
#include <stdio.h> int main(void) { if (3 > 2) ; // if 实际控制的是空语句 printf("AAA\n"); // 不受 if 控制,必定执行 printf("BBB\n"); // 不受 if 控制,必定执行 return 0; }3. 执行结果
AAA BBB4. 程序分析
| 步骤 | 执行内容 | 说明 |
|---|---|---|
| 第 1 步 | 判断3 > 2 | 条件成立 |
| 第 2 步 | 执行空语句; | 什么也不做 |
| 第 3 步 | 执行printf("AAA\n"); | 不受if控制 |
| 第 4 步 | 执行printf("BBB\n"); | 不受if控制 |
因此,即使if条件成立,程序也只是执行了一个空语句,真正的输出语句已经脱离了if控制。
八、条件不成立时更能看出错误
1. 错误示例程序
#include <stdio.h> int main(void) { if (1 > 2); printf("AAA\n"); printf("BBB\n"); return 0; }2. 实际等价形式
#include <stdio.h> int main(void) { if (1 > 2) ; // 条件不成立,不执行空语句 printf("AAA\n"); // 不受 if 控制,仍然执行 printf("BBB\n"); // 不受 if 控制,仍然执行 return 0; }3. 执行结果
AAA BBB4. 错误原因
虽然1 > 2是假,但printf("AAA\n");并不属于if的控制范围,因此仍然会执行。
这正是if后误加分号最典型的逻辑错误。
九、正确写法:不要在 if 条件后加分号
1. 控制一条语句
if (1 > 2) printf("AAA\n"); printf("BBB\n");执行结果为:
BBB2. 控制多条语句
如果希望if控制多条语句,必须使用花括号。
#include <stdio.h> int main(void) { if (3 > 2) { printf("AAA\n"); printf("CCC\n"); } printf("BBB\n"); return 0; }执行结果为:
AAA CCC BBB十、if 后加分号与不加分号的对比
| 写法 | 是否推荐 | if 实际控制的内容 | 输出语句是否受 if 控制 |
|---|---|---|---|
if (条件) printf(...); | 可以,但不够清晰 | printf语句 | 是 |
if (条件) { printf(...); } | 推荐 | 花括号内的语句块 | 是 |
if (条件); printf(...); | 不推荐 | 空语句; | 否 |
if (条件) ; | 特殊场景才使用 | 空语句; | 无输出语句受控制 |
十一、语法错误、警告和逻辑错误的区别
if (条件);这种写法容易误导初学者,因为它通常不是语法错误。
1. 语法错误
语法错误是指代码不符合 C 语言语法规则,编译器无法正常编译。
例如:
if (3 > 2) printf("AAA\n")这里少了分号,可能导致编译错误。
2. 编译警告
某些编译器在开启较严格警告选项时,可能会提示if后存在空语句。
例如使用 GCC 编译时,可以打开警告选项:
gcc -Wall if_empty_statement.c -o if_empty_statement.exe-Wall的作用是开启常见警告。对于初学者来说,警告也应认真查看,因为很多警告意味着程序可能存在潜在错误。
3. 逻辑错误
逻辑错误是指程序能编译、能运行,但运行结果不符合设计意图。
例如:
if (1 > 2); printf("AAA\n");这段代码语法上成立,但printf("AAA\n");不受if控制,因此会输出不符合预期的结果。
十二、VSCode 中的验证方法
1. 新建源文件
在 VSCode 中新建文件:
if_empty_statement.c2. 输入测试代码
#include <stdio.h> int main(void) { if (1 > 2); printf("AAA\n"); printf("BBB\n"); return 0; }3. 编译程序
如果使用 GCC,可以在 VSCode 终端中执行:
gcc -Wall if_empty_statement.c -o if_empty_statement.exe4. 运行程序
./if_empty_statement.exe5. 观察结果
实际输出为:
AAA BBB这说明printf("AAA\n");并没有受到if (1 > 2)的控制。
十三、建议养成的编码习惯
为了避免if后误加分号造成逻辑错误,建议初学阶段始终使用花括号。
推荐写法
if (条件) { 语句; }例如:
if (score >= 60) { printf("及格\n"); }不推荐写法
if (score >= 60) printf("及格\n");虽然这段代码语法正确,但以后添加第二条语句时容易出错。
错误写法
if (score >= 60); { printf("及格\n"); }这段代码中的if实际控制的是空语句,花括号中的代码块会无条件执行。
十四、本节要点总结
流程控制是看懂 C 程序的基础。
if 语句用于根据条件决定是否执行某条语句。
if (条件);中的分号表示一条空语句。if (条件);通常不是语法错误,但很容易造成逻辑错误。如果
if后误加分号,后面的printf语句通常不再受if控制。初学阶段建议所有
if语句都使用花括号。在 VSCode 中编译时建议使用
-Wall选项查看潜在警告。学习流程控制时,应重点分析“哪条语句受控制,哪条语句不受控制”。
十五、参考出处
《C程序设计(第五版)》谭浩强,第 3 章“最简单的 C 程序设计——顺序程序设计”
《C程序设计(第五版)》谭浩强,第 4 章“选择结构程序设计”
郝斌《C语言自学入门教程》对应内容:流程控制、if 语句常见错误、空语句问题。