2
 #define address (*((unsigned int *)10))

 void main()
 {
     unsigned int *p;
     p = &(address);
 }

'p' 的值为 10。如何评估上述表达式?不是从最里面的支架到最外面的支架吗?但如果是这样,那么 '&' 有一个没有意义的左值。我知道它会转换为 &*(10) ,其值为 10。

4

4 回答 4

2

p = &(0)不是在编译期间归结为吗?

不,一点也不:编译器不知道地址 10 处有值 0。

它是高度不可移植的,可能应该提供一个方便的标识符 -address可用于从内存中定义的位置读取值。我想它来自嵌入式编程。

address可以解释为unsigned int位于地址 10 的变量,因此拼写错误,因为它的地址 - 10 - 只能由&address.

于 2013-07-30T15:02:20.303 回答
2

通常,当您正在处理您不理解的事情时,最容易采取这一步骤。您的问题是正确的:

不是从最里面的支架到最外面的支架吗?

所以让我们从那里开始。如果您使用宏的最内层大括号中的((unsigned int *)10)内容,它会做什么?此语句将文字 value 类型转换10为指向 unsigned int 的指针。我们现在有一个指向地址 10 的指针。正如@glglgl 所说,您的宏命名不正确。如果您希望宏成为地址,那么您将在此处结束。这是嵌入式编程中经常使用的一种技术,因此您可以准确地知道地址的用途(例如特定的外围寄存器)。

下一组大括号,(*((unsigned int *)10))取消引用我们刚刚类型转换的指针。所以宏实际上给了我们当前存储在 address 的值10

最后,当您将值分配给指针p = &(address);时,您只是获取存储在 address 的值的地址10,即 10。您可以很容易地陈述p = (unsigned int *)10;并得到相同的结果。

于 2013-07-30T15:33:06.017 回答
1

void main()应该是int main(void)。告诉您使用void main()的任何书籍或教程都是由不太了解 C 语言的人编写的。

宏展开后的主体main等价于:

unsigned int *p = &(*((unsigned int *)10));

如果一元运算符的操作数是一元运算&符的结果*,则两个运算符都被省略(这在标准中明确说明),因此上述等价于:

unsigned int *p = (unsigned int *)10;

这将获取int10并将其从 转换intunsigned int*

整数到指针转换的结果是实现定义的,但“旨在与执行环境的寻址结构一致”。

因此,如果“内存地址 10”的想法有意义,那么上面的内容可能会设置p为该地址。

结果指针可能未正确对齐。在许多系统上,unsigned int是 4 个字节并且需要 4 个字节对齐;10 不是 4 的倍数。

该代码似乎是故意混淆的。简化版更直接,不太可能有用。

万一您知道unsigned int系统上的地址 10 有一个对象,并且您需要访问它,那么

unsigned int *p = (unsigned int *)10;

将是这样做的方法。

于 2013-07-30T15:37:34.080 回答
0

address 是指向内存地址(内存地址 10)的指针,二级间接。所以 &adress 是内存地址 10,所以 p 是内存地址 10。

于 2013-07-30T15:30:05.337 回答