1、初学 C 语言的人最容易犯的错误集锦(一)下面这些错误如果你不能一眼看出来,那么就需要非常注意这些细节了。这些错误虽然都很小,但是经常能让一个初学者郁闷好几天。我们将分析这些错误并给出避免出错的建议。错误 1#include void main()int i;for (i=1;ivoid main()int i;for (i=1;ivoid main()int i;for (i=1;iint main(int argc, char *argv)int i=333;if(i%2=0)printf(“偶数“);elseprintf(“奇数“);return 0;上面的代码编译的时候会报下面的错误:
2、error: syntax error before “else“在 if 语句中,如果有 else 子句,则在 if 后不应该使用分号。正确的代码应该是:#include int main(int argc, char *argv)int i=333;if(i%2=0)printf(“偶数“);elseprintf(“奇数“);return 0;总结:分号的问题是犯错率最高的一个错误。C 语言的初学者最容易迷糊的就是不知道什么地方该用分号,什么地方不应该放分号。原则就是:完整的语义之后才放分号。比如对于:if(i%7=0)printf(“%3d“,i) ;if 语句表示“如果。那么。”,“如
3、果。那么。”就是一个完整的语义,因此在 if 后不能添加分号。同样对于:if(i%2=0)printf(“偶数“);elseprintf(“奇数“);if。else。语句表示“如果。那么。否则”,“如果。那么。否则”就是一个完整的语义,因此在 else 之前不能添加分号。初学 C 语言的人最容易犯的错误集锦(二)下面的代码用来判断用户输入的年份是否是闰年:#include main()printf(“请输入年份:“);int a,k;scanf(“%d“,k=(a%4=0if(k=0)printf(“不是闰年“); if(k=1)printf(“是闰年“);system(“pause“);能看
4、出程序有什么问题吗?为什么无论输入什么都显示“是闰年”?很明显,程序中判断 k 是否等于 0 或者等于 1 的时候错误的使用了“=”进行值的相等判断而不是“=”。在 C 语言中“k=1”不仅是“把 k 变量赋值为 1”,而且如果把“k=1”当作表达式的话“k=1”还会有返回值,它的值就等于 k 赋值以后的值。=如果还不明白的话跟着我来看一个例子,试验代码如下:int i=3;printf(“%dn“,i=5);printf(“%dn“,i=5);上面的代码执行结果如下:05我们来分析一下上面代码,第二行是打印“i=5”的值,由于 i=3,所以 i 等于 5,而 C语言中“不等于”的值是 0,所
5、以第一行打印 0;第三行是首先执行表达式“i=5”的值,这个表达式首先将 i 赋值为 5,然后“i=5”也是有返回值的,它的返回值就是变量 i 的值,所以第三行会打印出 5。=“k=1”的值为 k 的值,而 k 等于 1,所以“k=1”的值就是 1,而 1 等于 TRUE,所以if(k=1)printf(“是闰年“);就永远都会执行了。同样“k=0”的值为 k 的值,而 k 等于 0,所以“k=0”的值就是 0,而 1 等于 FALSE,所以if(k=0)printf(“不是闰年“);就永远都不会得到执行了。明白了这个道理,我们以后在 if 语句等地方使用“=”的时候千万不要误写成“=”,可是
6、“人有失手,马有乱踢”,我们总会不经意的犯这样的错误,而且这样的错误很难查找,那么能不能从根本上防范这种错误呢?有经验的 C/C+开发人员编写类似于上面判断闰年的代码的时候一般会这么写:#include main()printf(“请输入年份:“);int a,k;scanf(“%d“,k=(a%4=0if(0=k)printf(“不是闰年“); if(1=k)printf(“是闰年“);system(“pause“);看出差别来了吗?好像没啥差别呀?仔细看:if(0=k)printf(“不是闰年“); 这里将“k=0”颠倒成了“0=k”,这有什么用吗?请上眼!比如编程的时候我将“=”误写成“
7、=”有什么后果呢?if(0=k)printf(“不是闰年“); 编译的时候编译器会报告“if(0=k)”这行代码有错误,因为 0 是一个常量数字,不能设置它的值。这样通过将待判断表达式的值放到变量之前的这样的方式就可以“打好预防针”,为防止失误起到了作用。这种技巧是有经验的开发人员经常使用的,因此建议大家在开发过程中也培养起这样的习惯,而且等你毕业求职面试、笔试的时候,如果你写出这样的代码风格的话,考官一定会认为你是一个有经验的开发人员,这样的话你得到 offer 还不容易吗?初学 C 语言的人最容易犯的错误集锦(三)从键盘输入一个数字保存到 int 中:int i;scanf(“%i“,i)
8、;这段代码有错吗?看起来好像没错,也可以编译通过,但是运行的时候我们输入要设置的字符会造成“程序内存访问冲突”之类的程序错误。为什么呢?注意 scanf 第二个参数是待设置变量的指针,而不是变量的值,比如要将用户输入的数字保存到变量 i 中的话要使用 scanf(“%s“,scanf(“%i“,初学 C 语言的人最容易犯的错误集锦(四)曾经有同学在如鹏网的官方 QQ 群中提了下面的问题:printf(“%c%c“,getchar(),getchar();输入 “ab “为什么显示为 b a?这个问题比较复杂,要理解的话首先要理解函数调用中的“参数列表求值顺序”的概念。这个概念是所有编程语言都会
9、涉及到的问题,并不局限于 C 语言,这也是一个“一通百通”的知识点,需要深刻理解。假设有下面的一个函数 f1:void f1(int i1,int i2,int i3)printf(“i1=%d,i2=%d,i3=%d“,i1,i2,i3);在调用函数的时候,如果给函数传递的是普通的变量那么并不会体会到“参数列表求值顺序”的概念,比如代码段“f1(a,b,c)”的含义是“调用 f1 函数,并且给 f1 函数的参数1、参数 2、参数 3 分别赋值为 a、b、c 三个变量”。那么如果是下面的代码呢:int i=10;f1(i+,i+,i+);很多同学都认为上边的代码会打印出“i1=10,i2=11
10、,i3=12”,但是运行以后你会发现与预想的完全相反:“i1=12,i2=11,i3=10”。这是和函数参数计算顺序(准确的讲应该叫“函数参数压栈顺序”)相关的,通俗的讲就是如果函数的参数不是简单的变量或者常量,而是需要进行计算的表达式、函数的时候,是按照从左到右还是从右到左的顺序计算函数的参数,C/C+的默认函数参数计算顺序是从右到左,也就是说对于“f1(i+,i+,i+)”来说会首先计算第三个参数、再计算第二个参数、再计算第一个参数,因此三个参数的值将会是“12、11、10”,这就不难解释貌似奇怪的执行结果了。明白了这个道理,对于本文开始的例子出现的怪异行为也就不会奇怪了,因为输入的 a 被做为第二个 getchar 的返回值,b 则被做为第一个 getchar 的返回值。其实 C/C+标准并没有规定函数参数计算顺序,不过主流的编译器都是从右至左的顺序。关于这个问题可以参考更多资料: