C常见错误小记(未完)

1、指针与NULL

下面这段代码会报错:

{
     int *a = NULL; 
     *a = 3; 
      printf("%d",*a); 
}

  指针初始化为NULL,还是没有分配内存,所以会报错。指针是个变量,就是个装地址的变量,是变量就可以重复使用。
而平时之所以让指针指向NULL,是防止误用了野指针修改随机内存。但具体使用前一定要保证已分配内存了。

2、NDEBUG与assert

  头文件assert.h定义的宏受NDEBUG的影响.如果预程序在处理这个头文件时已经定义了NDEBUG,assert宏的内容就定义为空,这意味着assert宏不在起作用.所以,可以在最终发布程序的时候可以使用-DNDEBUG关闭断言功能或者把#define NDEBUG加到每个源文件中,但这条语句必须放在#include <assert.h>之前.

1 #include<stdio.h>   
2  #define   NDEBUG  //要加在#include<assert.h>前面 #include<assert.h>
3 int main() 
4 {  
5      int x = 0;   
6     assert(x);      
7     printf("aa
"); return 0; 
8 }

  trace(),assert()都只是在DEBUG的模式下才起作用的,如果定义了NDEBUG,编译器会认为是非DEBUG的模式(虽然编译出来的程序还是很大,而且还可以进行调试),此时trace(),assert()就没有用了.就如同你编译成release版的时候这些没有用一样。efine DEBUG   会重新打开调试开关

3、作用域与static、extern

  

   举个例子,同一个工程下:

  (1)在file.c中定义全局变量int a = 9,则在file2.c中不允许在全局下重定义变量a,但允许在语句"extern int a;"后可以访问file.c中的a。

  (2)在file.c中定义全局变量static int a = 9,则a为file.c的文件作用域,在file2.c中无法访问。

4、不要写歧义的操作

比如下面这句话,对n的操作有歧义,究竟是左值中的n是n+1还是n呢?

 ThreadHandle[n]=CreateThread( NULL, 0, comp, &varr[n++], 0, NULL );

类似的,f1()*f2()中,哪个先计算呢,在C++中,规定操作数计算顺序的的只有(), ?:  和 , ,此外其他操作符并未指定操作数的求值顺序,这类表达式的行为没有明确定义。

所以若操作数计算顺序会影响结果,最好可以写成更清晰地形式

1 ThreadHandle[n]=CreateThread( NULL, 0, comp, &varr[n], 0, NULL );
2 n++; //不要把n的操作放在上面的表达式中,有歧义,易出错

  

原文地址:https://www.cnblogs.com/JesusAlone/p/3642568.html