⑴ c语言中x*(y)+z和x*y+z 的区别
这是宏替换的特点!
宏替换是在编译时,将源程序中与宏定义符合的代码进行“傻瓜”式替换。
如:
#define MAX(x,y,z) x*(y)+z
printf("%d/n", MAX(a+b.b+c,c+a) ); 在编译时替换成printf("%d/n", a+b*(b+c)+c+a );
而
#define MAX(x,y,z) x*y+z
printf("%d/n", MAX(a+b.b+c,c+a) ); 在编译时替换成printf("%d/n", a+b*b+c+c+a );
可见两个表达式在编译后的结果是不同的,因而结果不同!
⑵ c语言中宏替换时先求出实参表达式的值,然后再带入形参中运算求值,对不对啊为什么啊
不是这样的,宏替换是在预编译时将整个宏的表达式进行替换再进行编译的,举个例子讲如果你定义了如下宏:
#define fun(a) (a*a)
下面用的时候
int main()
{
int i = 5, j = 4;
int k = fun(i+j)
}
那么在预编译时首选会先将fun(i+j)替换成 i+j*i+j,即此时计算的时候会先算乘法i*j,那么k的值最终就是5+4*5+4 = 29,而不是(i+j)*(i+j)=81,当然如果你想实现后一种结果,则宏定义方法应该是下面这样的
#define fun(a) ((a)*(a))
相互学习,希望对你有帮助,不懂的话,再跟我讨论吧
⑶ 宏替换,宏展开到底分别在什么时候进行
//在宏 使用的时候 分为
宏定义 和 宏展开, 你那个 宏替换就是展开
宏定义是你自己写的 #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个
⑷ C语言中,下面有关宏替换的叙述中,不正确的是
宏替换是在预编译时完成的,预编译的功能是将头文件引入,并且将定义的宏按字面完成“傻瓜”式替换(即将符合宏的样式的字符串,替换成宏定义的字符串),宏名没有类型区分,它只是个字符串。因此,D是错的
⑸ 宏替换是在程序编译时完成的,不占用程序运行时间
是正确的,编译时预处理,不分配内存空间
⑹ C语言编译系统对宏替换的处理是在什么时候进行的
是正式工作开始之前的准备工作,所以宏替换是在对程序编译之前进行的。
宏替换是C/C++的预处者迟桥理中的一部分,对于宏定义中的形参,在替首猛换列表中,如果不是作为#或##的操作数,那么将对应实参完全展旦高开(相当于对实参进行求值),然后将替换列表中的形参替换掉,如果是#或##的操作数。
(6)宏替换是在编译扩展阅读:
宏的用途在于自动化频繁使用的序列或者是获得一种更强大的抽象能力。
计算机语言如C语言或汇编语言有简单的宏系统,由编译器或汇编器的预处理器实现。C语言的宏预处理器的工作只是简单的文本搜索和替换,使用附加的文本处理语言如M4,C程序员可以获得更精巧的宏。
宏的行为如同是函数对自身程序文本的变形,并且可以应用全部语言来表达这种变形。一个C宏可以定义一段语法的替换,然而一个Lisp的宏却可以控制一节代码的计算。
⑺ 宏替换只是字符替换,不占用编译时间是不是正确
宏是在预编译期间进行的,将代码中的指定字符转换
转换结束后,再进行编译
所以不占用编译时间