不知道你有没有遇到过这种让人抓狂的事情:在 VS2013 里写了一个很简单的 for 循环,想打印 1 到 10,按下 F5 运行,结果控制台上只孤零零地打印了一个数字就结束了?
#include<stdio.h>intmain(){inti;for(i=1;i<=10;i++);{printf("%d\n",i);}return0;}按 F5 运行,VS2013 编译通过,零报错,零警告。控制台只输出了一个11,然后程序就结束了。
那一瞬间,你是不是怀疑 VS2013 出了问题,或者自己写的循环逻辑哪里不对?明明 for 循环里写的是i <= 10,为什么只跑了一次就罢工了,而且打印出来的还是 11?
罪魁祸首:for 括号后面那个"隐形分号"
现在,我们瞪大眼睛再看一遍上面那段代码。仔细看 for 那一行,括号的最后面,是不是紧跟着一个不起眼的分号?
对,就是for (i = 1; i <= 10; i++);那个在右括号后面的分号。
在 C 语言的语法里,单独一个分号;是一条合法的语句,叫作"空语句"(null statement),意思就是"什么都不做"。
当你把分号紧贴在 for 的括号后面时,编译器会认为你想表达的是:
“给我循环 10 次,每次循环什么都不干。”
于是,for 循环老老实实地把i++执行了 10 次,从 1 自增到了 11。然后循环结束了。
循环结束后,程序继续往下走,遇到了大括号里的printf("%d\n", i);。此时i的值已经是 11 了,所以控制台上打印出了 11。
关键点来了:那个大括号{}根本不是 for 循环的循环体,它只是一个独立的代码块,跟在空语句后面,和 for 循环没有任何关系!这就是为什么你的循环"只跑了一次"——实际上循环跑了 10 次,但大括号里的代码只执行了 1 次,因为它不在循环里!
避坑方案
知道了原因,解决方案就很简单了——把 for 括号后面的分号删掉。
#include<stdio.h>intmain(){inti;for(i=1;i<=10;i++){printf("%d\n",i);}return0;}这样编译运行,控制台就会乖乖地打印出 1 到 10,一切正常。
如何在 VS2013 里发现这种"隐形 Bug"?
VS2013 的编译器对这种情况默认不会报错,也不会弹 warning。因为从语法上来说,这真的没有错——空语句是标准语法。
但有一个小技巧可以帮你提前发现这类问题:在 VS2013 里,如果你把鼠标悬停在for (...);那个分号上,编译器有时候会用智能提示告诉你这里有一个"空语句"或"null statement"。养成写完代码后扫一眼 for、while、if 括号末尾有没有多余分号的好习惯,能帮你省下大量的调试时间。
还有一种更简单粗暴的防范方法:养成把{直接写在 for 括号同一行末尾的习惯,就像for (...) {这样,这样你就没有机会在中间插一个分号了。
今日思考题
如果我写的是while (i <= 10);后面加个分号,会发生什么?按 F5 运行后,程序会正常结束,还是会直接"卡死"?动手试一下,把你的发现写在评论区!
标签:#C语言#for循环#空语句#VS2013#避坑指南