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

4 回答 4

3

当你扩展你的宏时,你会得到:

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

忘记(int *)你就会得到

(*(&a)) = 20

这等于:

a = 20;

因此,您正在改变a!

于 2012-12-16T11:47:09.040 回答
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
于 2012-12-16T11:46:47.697 回答
1

假设你有:

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

上面所做的是将 10 分配给指向的整数b

你的宏做几乎相同的事情,b替换为&a(和无操作演员)。

于 2012-12-16T11:47:31.293 回答
1

取消引用指针的结果是L-value,因为它有一个地址;它当然可以分配。

考虑一个更简单的例子:如果p是一个数组或一个指针,你当然可以分配给p[0],如

p[0] = 20;

现在回想一下,p[0]这与*p. 现在扩展你的宏:

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

这相当于

(&a)[0] = 20;

这当然是对a自身的有效(尽管有些非正统)分配。

于 2012-12-16T11:50:09.683 回答