我不知道如何表達我的問題。代碼如下,請告訴我爲什麼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);
}
我不知道如何表達我的問題。代碼如下,請告訴我爲什麼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);
}
取消引用指針的結果是L-value,因爲它有一個地址;它當然可以分配。
考慮一個簡單的例子:如果p
是一個數組或指針,你當然可以分配給p[0]
,如
p[0] = 20;
現在回想一下,p[0]
相同*p
。現在擴大您的宏:
*((int*)&a) = 20;
這相當於
(&a)[0] = 20;
這肯定是a
本身的一個有效的(儘管有點非正統)分配。
的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
當你展開你的宏,你會得到:
(*(int *)(&a)) = 20
忘記(int *)
,你會得到
等於:
a = 20;
因此你改變的a
價值!
假設您有:
int *b = ...;
*b = 10;
什麼上面所做的是分配10的整數b
點。
你的宏幾乎完全一樣,b
取代&a
(和一個非操作演員)。
當然,它不能改變a的地址。我改變了存儲在地址的值。這是一個,BTW。 – wildplasser
我會感興趣的知道你的理論應該發生什麼以及爲什麼。 –