2012-12-16 47 views
-1

我不知道如何表達我的問題。代碼如下,請告訴我爲什麼a的值發生了變化?在我看來,在GET macro剛剛返回的a的價值,a不是地址...宏值被分配時發生變化

#include <stdio.h> 

#define GET(addr) (*(int *)(&addr)) 

int main() 
{ 
    int a = 10; 
    GET(a) = 20; 
    printf("%d\n", a); 
} 
+0

當然,它不能改變a的地址。我改變了存儲在地址的值。這是一個,BTW。 – wildplasser

+3

我會感興趣的知道你的理論應該發生什麼以及爲什麼。 –

回答

1

取消引用指針的結果是L-value,因爲它有一個地址;它當然可以分配。

考慮一個簡單的例子:如果p是一個數組或指針,你當然可以分配給p[0],如

p[0] = 20; 

現在回想一下,p[0]相同*p。現在擴大您的宏:

*((int*)&a) = 20; 

這相當於

(&a)[0] = 20; 

這肯定是a本身的一個有效的(儘管有點非正統)分配。

1

GET(a) = 20線擴展爲:

(*(int *)(&a)) = 20; 

讓我們擺脫了多餘的演員和的外括號:

*(&a) = 20; 

這顯然是一個分配給a因爲它等同於:

a = 20; 

如果你的目標是防止意外使用GET()作爲左值,你可以改變它,像這樣:

#define GET(addr) ((int)addr) 

有了這個,試圖編譯代碼失敗

test.c:8:12: error: lvalue required as left operand of assignment 
3

當你展開你的宏,你會得到:

(*(int *)(&a)) = 20 

忘記(int *),你會得到

​​

等於:

a = 20; 

因此你改變的a價值!

1

假設您有:

int *b = ...; 
*b = 10; 

什麼上面所做的是分配10的整數b點。

你的宏幾乎完全一樣,b取代&a(和一個非操作演員)。

相關問題