#define
0.定义
宏常量,也称符号常量(Symbolic Names or Constants),是指用一个标识符号代表的一个常量,这时该标识符号与此常量等价。宏定义的一般形式为:
#define 标识符 字符串
凡在源程序中发现该标识符时,都用其后指定的字符串来替换。标识符与字符串之间可以有多个空白符,但字符串后只能以换行符终止,且除非特殊需要一般不出现分号。
1.为什么要引入宏定义?
在对一些常见的变量,字符串等,进行宏定义时,系统在编译期间,就会自动替换,如果不进行宏定义,一般如果此类变量,字符串等,需要修改,就需要对源文件中它们出现的地方一一修改,效率比较低,而此种宏定义后,只需要修改一次,实现批量修改,效率较高.而且有些数字或字符很麻烦,每次都要输入,就显得很繁琐,而且容易出错,而采取此宏定义,就很方便和易于维护,提高程序的可读性。
2.宏定义的边界问题
宏有一种带参数的形式,用起来很像函数,例如:
#define MAX(A,B) ((A) > (B) ? (A) : (B))
SO,下面代码
print("%d", MAX(1,2));
将被替换为
print("%d", ((1) > (2) ? (1) : (2));
输出结果为2。
带参数的宏使用起来很像函数,但两者的机理和运行效果截然不同。宏时预处理阶段进行调用,函数是在运行时调用。
预处理在编译发生之前,并不检查语法。如果宏替换出现问题,编译器将报语法错误,但编译器看到代码时,宏已经都不存在了。更严重的情况是,编译器根本不报错,但运行结果不对。例如,将MAX定义为:
#define MAX(A,B) A > B ? A : B
所有括号取消了,来看这段代码:
print("%d",MAX(MAX(2,1),3));
感觉应该是3,但实际是2
printf("%d",2 > 1 ? 2 : 1 > 3 ? 2 > 1 ? 2 : 1 : 3 );
计算完后就是2。
所以,该加括号加括号!
当然括号不是万能的。
例如,
print("%d", MAX(i++,3));
表面上看i只加一次,实际上被替换后:
print("%d", i++ > 3 ? i++ : 3 );
i会被加两次。
3.条件编译
是使某些代码仅在特定的条件成立时才会被编译。由#if,#ifndef,#else,#elif和#endif组合实现。请看下面代码:
#define USE_INT
#if define USE_INT
int fo;
int bar;
#else
long fo;
long bar;
#endif
如果USE_INT被定义,那么生效的是if下面的语句,否则是else下的语句。
sizeof
参考http://blog.csdn.net/freefalcon/article/details/54839