2013-05-04 88 views
1

所以我基本上試圖做一個交換兩個t類型參數的SWAP(t,x,y)宏。我試圖考慮當這兩個參數的形式爲宏SWAP(t,x,y)交換t類型的兩個參數

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; 
} 

任何想法可能會錯呢?

回答

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

v[i++]int元素,但你是在分配給一個指針對象:

T *p = x; 

所以當你解引用pT z = *p;你得到一個段錯誤。如果你想要一個指向元素的指針,使用&運算符。

此外v[i++]有一個副作用(它修改i++),你不應該通過在宏調用中有副作用的表達式。

+0

謝謝。現在一切都好!這個「副作用」問題是我想要解決的真正問題。 – Rayhunter 2013-05-04 18:56:44

+0

請downvoter,解釋你downvote。 – ouah 2013-05-05 01:59:24

+0

如果其中任何一個參數都是'p' - 這將失敗(但我的投票不過)。下面包括自己的答案。 – ideasman42 2015-03-27 15:10:56

3
#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)]); 
+0

是的,正好:) – Rayhunter 2013-05-04 22:44:55

+1

如果可能,最好引用宏參數名:'#define SWAP(T,x,y){T * p =&(x),* q =&(y),z = * p; * p = * q; * q = z; }'。這減少了宏的文本替換與C語法交互時發生的錯誤。 – 2013-05-05 12:50:09

+0

@EricPostpischil這是一個好點,因爲結果可能因操作符優先級而異。 它已修復。謝謝。 – BLUEPIXY 2013-05-05 13:06:17

0

將該溶液通過僅一次instansiating參數和通過重用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)