C语言#define宏的扩展

来源:互联网 发布:兄弟连linux 编辑:程序博客网 时间:2024/06/05 03:11

使用带参数的宏定义可完成函数调用的功能,又能减少系统开 销,提高运行效率。正如C语言中所讲,函数的使用可以使程序更加模块化,便于组织,而且可重复利用,但在发生函数调用时,需要保留调用函数的现场,以便子 函数执行结束后能返回继续执行,同样在子函数执行完后要恢复调用函数的现场,这都需要一定的时间,如果子函数执行的操作比较多,这种转换时间开销可以忽 略,但如果子函数完成的功能比较少,甚至于只完成一点操作,如一个乘法语句的操作,则这部分转换开销就相对较大了,但使用带参数的宏定义就不会出现这个问 题,因为它是在预处理阶段即进行了宏展开,在执行时不需要转换,即在当地执行。宏定义可完成简单的操作,但复杂的操作还是要由函数调用来完成,而且宏定义 所占用的目标代码空间相对较大。所以在使用时要依据具体情况来决定是否使用宏定义。


形式参数不能用带引号的字符串替换。
但是,如果在替换文本中,参数名以#作为前缀则结果将被扩展为 由 实际参数 替换 此实际参数的带引号的字符串。
例如,可以将它与字符串连接运算结合起来编写一个调试打印宏:
#define dprint(expr) printf(#expr “ = %/n”,expr)
使用语句 dprint(x/y);
调用宏时,该宏将被扩展为:printf(“x/y”“ = %/n”,x/y);
其中的字符串被连接起来了,这样便等价于printf(“x/y = %/n”,x/y);

在实际参数中,每个双引号 “ 将被替换为 /” ;反斜杠/将被替换为//,因此替换后的字符串是合法的字符串常量。

预处理运算符 ## 为宏扩展提供了一种连接实际参数的手段。如果替换文本中的参数与 ## 相邻,则该参数将被实际参数替换,##与前后的空白符将被删除,并对替换后的结果重新扫描。
例如,下面定义的宏paste用于连接两个参数
#define paste(front, back) front ## back
因此,宏调用past(name,1)的结果将建立记号name1.


c语言中没有swap这个函数,C语言不支持重载,也没有模版的概念,所以对于每一种类型,都要写出相应的swap,如
intSwap   (int   *,   int   *);  
longSwap   (long   *,   long   *);  
stringSwap   (char   *,   char   *); 

宏定义swap(t,x,y)以交换t类型的两个参数(要使用程序块结构)。
程序如下:
#include <iostream.h>

#define SWAP(t,x,y) /
{/
t temp = *y;/
*y = *x;/
*x = temp;/
}

main()
{
int a = 10, b = 5;
SWAP(int,&a,&b)
cout << a << endl << b<<endl;
}
用/换行,/的意思是說把下一行看作和這行是同一行.換行必須要反斜杠,而且/後面直接回車,不能有空格。

 

 

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x

我们假设:x=1,则有:

A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"