优美的C语言 --- 灵活使用C的宏定义(转)
时间:2007-06-01 来源:wwling2001
http://www.i170.com/Article/63502/trackback
C语言里面没有通用类型,在某些程序设计的时候,可能会感觉到和不方便,解决办法之一就是使用宏定义。这里先看一个简单的例子:
#include <stdio.h>
#define getVariable(Type, name, value) \
Type name = value
int main(){
getVariable(int,a,1);
getVariable(char,b,'p');
getVariable(char *,c,"hello");
printf("a = %d\nb = %c\nc = %s\n",a,b,c);
return 0;
}
输出结果:
下面说一下宏定义(或称之为宏替换)的用法:
1) 形式:
#define 名字 替换文本
名字后可以接任意字符串,名字和define以及替换文本用空白字符分割。替换文本如果比较长,需要换行书写,那么需要在行尾加上\
2) 作用域:
从定义处到文件的结束
3) 带有变元的宏定义
一个最常见的例子是:
#define max(A,B) ((A) > (B) ? (A) : (B) ) // 带有变元 A,B
这里仅仅是一个替换,而不涉及到参数传递的问题,因此,绝对不能把 max() 看为一个函数,比如说:
max(i++,j);
这里i++只是单纯的被替换而已,所以,等同于:
i++ > j ? i++ : j
这样就做了2次加一运算
另外还可能出现的问题,比如
#define square(x) x*x
假如是square(i+2);
那么替换之后为 i+2*i+2,等价于 i + (2 * i) +2 ,结果显然和 (i + 2) * (i + 2) 不同
4) #变元 的含义
#define print(a) printf(#a);
这里#a 等价于 "a"。也就是说 #变元 被替换成为 "变元"
假如输入 print("a"),这里 " 被替换成为 \" , \ 替换成为 \\
5) ## 的含义
##表示连接,比如 a##b 就等价与 ab ,注意不是 "ab"(区别于#)
#define test(a) a##b; 这里先会替换a,再连接,比如 test(int),a##b 就等价与 inta
实例,编写一个swap宏,能够交换两个变量的值
#include <stdio.h>
#define swap(Type,a,b) \
Type tmp##Type;\
tmp##Type = a;\
a = b;\
b = tmp##Type;
int main(){
int a = 1,b = 2;
swap(int,a,b);
char c = 'a',d = 'b';
swap(char,c,d);
printf("a = %d\nb = %d\n",a,b);
printf("c = %c\nd = %c\n",c,d);
return 0;
}
结果:
$ ./app
a = 2
b = 1
c = b
d = a
这里要注意的是:
1) 以下代码是无法通过编译的:
#define swap(Type,a,b) \
Type tmp;\
tmp##Type = a;\
a = b;\
b = tmp;
int main(){
int a = 1,b = 2;
swap(int,a,b);
char c = 'a',d = 'b';
swap(char,c,d);
printf("a = %d\nb = %d\n",a,b);
printf("c = %c\nd = %c\n",c,d);
return 0;
}
因为,swap会被替换两次,替换之后就会得到这样的语句:
int tmp;
char tmp;
这里明显的重复定义了。
因此,不论怎么样,一定要记住,宏定义仅仅是替换而已和函数不同
2) 因为是简单的替换,所以不用这样的调用方式: swap(int,&a,&b); swap不是一个函数,没有形参和实参
http://www.i170.com/Article/63502/trackback