一,空语句
空语句“;”也是一条语句,该语句什么都不执行。常见错误为紧跟在if或循环语句之后,如if(); for();等,如果后面没有{},则默认空语句为if(或for)条件成立时执行的语句。你的在某些条件下才能执行的语句,忽略条件限制而执行。
二,=与==
C语言中=与==是不同的操作符号,=是用来赋值的,==是用来判断的,如果二者颠倒,则会带来意想不到的错误。
(1)用=来判断,
如 if (x=2){}, if (x=0){}等,表达式x=2永远返回真,x=0永远返回假。
(2)用==来赋值
如 x==2; 语句执行完后,x仍为原来的值,该语句没有达到实际效果。
同样,&与&&,|与||等。
三,if else嵌套
else与最近的未匹配的if匹配,不能单纯从缩进上来实现你想要的效果,忽略{}会带来程序上的混乱。
例如:
本意想让else与第二个if匹配,但编译器却让else与第一个if匹配。
再如:
编译器会让else与第二个if匹配。
为了确保这种情况不再发生,请在每个if/else后面加{},同样for/while后面也要{},哪怕后面只有一条语句。
四,宏定义
宏定义是一种字符替换,在编译时完成,关于它的使用错误,是很多的。
例如求绝对值的宏定义,#define abs(x) ((x)>0?(x):-(x))
(1)宏定义后面不能跟分号
(2)宏定义的空格
如果abs与(x)之间存在空格,则编译时出现错误。
(3)小括号的缺失
这种情况下,对于单个变量,不会出现错误,但对于一个表达式,则求的结果不是我们想要的结果,如abs(a-b);
所以下面情况会带来错误:
#define abs(x) (x>0?x:-x)
#define abs(x) x>0?x:-x
#define abs(x) ((x)>0?(x):(-x))
(4)二次求值的变量
对于abs(x),如果我们这样调用abs(x++),得到的结果是x+1的绝对值,而不是|x|。因此,应该把该句修改为abs(x);x++;
(5)宏定义不是数据类型
如果#define int32 int *
定义变量int32 a, b;
则变量a为指针变量,b为普通整形变量,而非指针变量。
(6)宏定义的函数
例如两个数的交换,#define swap(a,b,t) (t)=(a); (a)=(b); (b)=(t);
如果用在if下,则if要加{},因为swap会扩展出3条语句。
更好的写法是:
五,内存申请和释放
假如有结构体:
当我们malloc申请节点空间的时候,别忘了给name申请空间。
当我们free释放节点空间的时候,别忘了释放name指向的空间。
六,switch
switch中的语句是按顺序向下执行的,如果到某case分支后,跳出switch,别忘了加break。
七,字母o与数字0
字母o与数字0在某些编辑器中很相似,注意不要写错,并且,字母o与数字0在键盘上的位置很靠近,注意不要打错。
同样的问题,还有字母l与数字1与|(或)。
八,字符串长度大小的比较
下面的if判断是错误的:
if (strlen(s1) - strlen(s2) >= 0)
因为strlen返回类型为size_t,无符号整数,两个数相减永远>=0,没有达到你所期望的结果。
正确的比较:if (strlen(s1) >= strlen(s2))