程序的执行
1.预编译
2.编译生成汇编文件
3.编译生成目标文件
4.和库文件一起生成执行文件
预编译:提前编译
宏定义:在预编译期间执行
定义:提前编译
#define A 12
后面没有;号,后面也可以由参数
#define ADD(A, B) A+B
但是在main函数中调用的时候如果用 2 * ADD(A, B)这样就会出错, 所以需要加上一个()
#define ADD(A, B) (A+B)
#define MAX(A, B) ( A > B ? A : B)
但是这个函数的情况下在主函数中使用的话如果用MAX(A, 5 > 4 ? 5 : 4 )就会出错, 这个时候需要需要把每个变量都加上()
改进如下#define MAX(A, B) ( (A) >( B) ? (A) : (B));
但是如果MAX(2++, 4) ; 这样不仅结果出错,而且也改变了原来的值,这样就需要两个变量来保存2++和4的值
在c99的标准下有复合语句
int i = ({int a = 3; int b = 5; a + b;});
这个时候i就等于a + b的值,所以上述问题可以改成
#define MAXVALUE3(A, B) ({int temp1 = (A); int temp2 = (B); temp1 > temp2 ? temp1 : temp2; })
但是这样也会有个问题,就是传入的类型不一定是int型,所以可以修改成如下用形式:
#define MAXVALUE4(A, B) ({__typeof__(A) temp1 = (A); __typeof__(A) temp2 = (B); temp1 > temp2 ? temp1 : temp2; })
typeof前后是两个_而不是一个,这点要注意
其实这样还会有一个问题,就是temp1这样也可能会重名
系统中有函数MAX
#if !defined(MAX)
#define __NSMAX_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__b,L) : __NSX_PASTE__(__a,L); })
#define MAX(A,B) __NSMAX_IMPL__(A,B,__COUNTER__)
#endif
#define __NSX_PASTE__(A,B) A##B
__COUNTER__是一个计数器,开始的时候是1,以后的时候每次执行一次加1,这样就不会重名了({ __typeof__(A) __NSX_PASTE__(__a,L) = (A);就是把A给了__a##(__COUNTER__)这个累加器是随着调用的时候而改变,所以这个时候所有的用户名是不同的