宏替换,宏展开到底分别在什么时候进行?

今天看到:宏替换在编译预处理时完成。
又看到:宏展开在编译时进行。
重点是还看到了:以#define开头都是在编译预处理时完成。
宏替换和宏展开都是以#define开头的啊?这不就矛盾了吗。求知道的解释,谢谢!

  首先,宏是C编译系统的预处理,何谓“预”?即是正式工作开始之前的准备工作。

  所以宏替换是在对程序编译之前进行的。

  其次,C程序由源程序变为可执行文件的三个阶段是:

  预处理阶段,由预处理器对程序文本中的宏进行展开。

  编译阶段,由编译器对经过预处理后的程序进行编译,并生成目标文件

  链接阶段,则链接器对目标文件和用到的函数库文件进行链接,生成可执行文件。

  因此,宏展开是在预处理阶段完成的。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-07-29
//在宏 使用的时候 分为

宏定义 和 宏展开, 你那个 宏替换就是展开

宏定义是你自己写的 #define
然后展开在预编译时候处理
这个时候编译器先扫描一遍文件 把用到宏的地方都做字符替换

比如
#define M 1

int a = M;
那么预编译的时候就把 M 替换成1

注意宏只做文本替换,所以
比如 #define MUL(__x__, __y__) __x__ * __y__

int a = MUL(a + b, c+ d);
会被替换成 int a = a + b * c + d // 可能就会和初衷违背(如果你想做的是 (a + b) * (c + b))

从展开的角度来说 因为宏是可以嵌套的 所以宏在替换的时候 我们叫做展开

比如 做一个函数参数声明
#define PARAMS_SET_1(__type__, __name__) __type__ __name__
#define PARAMS_SET_2(__type__, __name__) __type__ __name__##1, __type__ __name__##2

//... 定义N个 PARAMS_SET_N
#define PARAMS(__size__, __type__, __name__) PARAMS_SET_##__size__(__type__, __name__)

然后 定义函数

int foo(PARAMS(2, int, n));
那么预编译的时候宏会这样展开

1, int foo(PARAMS_SET_2(int, n));
2, int foo(int n1, int n2);

另外注意就是编程的时候 由于宏只是文本替换,缺少类型检测 以及运算顺序这样的功能,所以要少用宏

上面所有的宏都有替换的方案
#define M 1 替换方案
struct M
{enum {value = 1} };
int a = M::value;

#define MUL(__x__, __y__) __x__ * __y__ 替换方案
template<int x, int y>
struct MUL
{enum{value = x * y}};

int a = MUL<10 + 20, 10 + 30>::value;

最后一个PARAMS的替换方案就是函数重载
template<typename T>
int foo(T n1);

template<typename T>
int foo(T n1, Tn2);

//后面定义N个本回答被提问者和网友采纳
第2个回答  2013-07-29
就是在编译预处理时进行
主要就是文本替换, 对代码里定义的macro宏替换成你定义的东西
第3个回答  2013-07-29
预处理就是宏展开
在编译之前完成
相似回答