我不知道如何表达我的问题。代码如下,请告诉我为什么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 :(得分:3)
当您展开宏时,您会得到:
(*(int *)(&a)) = 20
忘记(int *)
,你得到
(*(&a)) = 20
等于:
a = 20;
因此,您正在更改a
!
答案 1 :(得分: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
答案 2 :(得分:1)
说你有:
int *b = ...;
*b = 10;
以上所做的是将10分配给b
指向的整数。
你的宏几乎完全相同,b
替换为&a
(以及无操作演员)。
答案 3 :(得分:1)
取消引用指针的结果是L-value,因为它有一个地址;它当然可以分配。
考虑一个更简单的示例:如果p
是数组或指针,您当然可以分配给p[0]
,如
p[0] = 20;
现在回想一下p[0]
与*p
相同。现在展开你的宏:
*((int*)&a) = 20;
这相当于
(&a)[0] = 20;
这肯定是a
本身的有效(尽管有些非正统)的分配。