您的位置:首页 > 其它

宏定义

2016-01-08 14:55 405 查看
1,定义一个宏,计算数组的长度

#define ARRAYSIZE(a) sizeof(a)/sizeof(a[0])

2,定义一个宏,计算结构体中成员的偏移

#define offsetof(s,m) (size_t)&(((s *)0)->m)

3,多语句宏:

在程序设计中,另外一个很经典的算法就是将两个数进行交换。比如有2个整数:

int a = 10;

int b = 20;

交换后,a的值为20,b的值为10。在程序里面,必须要使用一个临时变量,来先把a的值保存起来,然后再把b的值赋给a,再把临时变量保存起来的a的值赋值给b。如果不用临时变量把a的值保存起来,那么当把b的值赋给a的时候,a的值就会丢失。 错误的写法如下:

a = b; //a的值丢失

b = a;//a和b的值最终都是b的值

正确的写法:

int tmp = a; //使用tmp变量保存a的值

a = b;

b = tmp;

上面的算法可以用宏来定义如下:

#define SWAP(a,b)

{ \

int tmp; \

tmp = a; \

a= b; \

b = tmp; \

}

上面的宏定义中,每行语句都用一个’\’来连接,用来将两个int类型的整数交换。然后在程序中使用这个宏定义如下:

void main(void)

{

int a = 10;

int b = 20;

SWAP(a, b);

printf(“a=%d, b=%d\n”, a, b);

}

这种对于多条语句的定义方法,虽然在普通的时候一般不会出现什么问题。但是,来看看下面的条件语句:

If (x>y)

SWAP(a, b);

else

SWAP(a,b);

如果对上面的条件语句进行宏展开,就得到了下面的程序:

if (x>y)

{

int tmp;

tmp = a;

a= b;

b = tmp;

};

else

{

int tmp;

tmp = a;

a= b;

b = tmp;

};

很显然,else语句部分会和if语句被;语句分割,所以会出现一个语法错误。即else语句会找不到if语句与之配对了。

于是,多余多条语句定义的宏,一般采用do-while(0)的格式来定义:

#define SWAP(a,b)

do { \

int tmp; \

tmp = a; \

a= b; \

b = tmp; \

}while(0)

这样,上面的程序展开之后:

if (x>y)

do{

int tmp;

tmp = a;

a= b;

b = tmp;

}while(0);

else

do {

int tmp;

tmp = a;

a= b;

b = tmp;

}while(0);

这样宏定义中的语句也只执行一次就退出了do-while循环,也避免了上面宏定义出现的一个特殊错误。

4,宏就是简单替换。记住这是简单的替换而已,不要在中间计算结果,一定要替换出表达式之后再算。

比如#define MAX(a,b) ((a)>(b)?(a):(b))

则遇到MAX(1+2,value)则会把它替换成:

((1+2)>(value)?(1+2):(value))

5,对于宏的二义性,来看看下面的例子。从下列选项中选择不会引起二义性的宏定义是:

A、 #define POWER(x) x*x

B、 #define POWER(x) (x)*(x)

C、 #define POWER(x) (x*x)

D、 #define POWER(x) ((x)*(x))

分析:

A.#define POWER(x) x*x

如果调用POWER(5+6),本意是 (5+6)*(5+6)=121,实际却是:5+6*5+6=41

B.#define POWER(x) (x)*(x)

如果调用POWER(5+6)/POWER(5+6),本意是得到结果为1,实际却是:(5+6)*(5+6)/(5+6)*(5+6)=11*11/11*11=121

C.#define POWER(x)(x*x)

如果调用POWER(5+6)+POWER(5+6),本意是 (11*11)+(11*11)=121+121=242,实际却是: (5+6*5+6)+(5+6*5+6)=41+41=82

D.没有二义性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: