宏交换(t,x,y)交换类型为t的两个参数

所以我基本上试图创建一个交换两个t类型参数的SWAP(t,x,y)宏。 当这两个参数都是这种forms时,我试图想到解决这个问题

v [i ++]和w [f(x)],即SWAP(int,v [i ++],w [f(x)])。

下面的代码基本上崩溃了……

#define SWAP(T,x,y) {T *p = x; T *q = y; T z = *p; *p = *q; *q = z;} int f (int x){ return (0-x); } int main(void) { int v[] = {1,2,3}; int i = 0; int w[] = {4,5,6}; int x = -1; int *p = v; int *q = w; SWAP(int*, v[i++],w[f(x)]); return 0; } 

什么想法可能会出错?

 SWAP(int*, v[i++],w[f(x)]); 

v[i++]是一个int元素,但是你将它分配给一个指针对象:

 T *p = x; 

所以你什么时候在T z = *p;中取消引用T z = *p; 你得到一个段错误。 如果需要指向元素的指针,请使用&运算符。

此外v[i++]有副作用(它修改了i++ ),你永远不应该传递在宏调用中有副作用的表达式。

 #define SWAP(T,x,y) {T *p = &(x); T *q = &(y); T z = *p; *p = *q; *q = z;} ... SWAP(int, v[i++], w[f(x)]); 

该解决方案通过仅重新设置参数一次并通过重用SWAP作为标识符来避免副作用。

 #define SWAP(type, a_, b_) \ do { \ struct { type *a; type *b; type t; } SWAP; \ SWAP.a = &(a_); \ SWAP.b = &(b_); \ SWAP.t = *SWAP.a; \ *SWAP.a = *SWAP.b; \ *SWAP.b = SWAP.t; \ } while (0)