为什么以及如何运作?

时间:2013-07-30 14:55:29

标签: c pointers

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

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

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

4 个答案:

答案 0 :(得分:2)

  

在编译过程中它不会归结为p = &(0)吗?

不,完全没有:编译器不知道地址10处的值为0。

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

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

答案 1 :(得分:2)

通常情况下,当您正在处理一些您不理解的事情时,最简单的方法就是采取这一步骤。你提出问题的方法是正确的:

  
    

难道不是从最里面的支撑到最外面的支撑吗?

  

让我们从那里开始吧。如果你采用宏的最里面的括号((unsigned int *)10),它会做什么?此语句将文字值10进行类型转换,以指向unsigned int。我们现在有一个指向地址10的指针。正如@glglgl所说,你的宏命名不正确。如果您希望宏是一个地址,那么这就是您要结束的地方。这是一种常用于嵌入式编程的技术,因此您可以准确地知道 一个地址(例如特定的外设寄存器)。

下一组大括号(*((unsigned int *)10))取消引用我们只是强制转换的指针。因此宏实际上为我们提供了当前存储在地址10的值。

最后,当您将值分配给指针p = &(address);时,您只需获取存储在地址10的值的地址,即10。您可以轻松地说明{{ 1}}并得到相同的结果。

答案 2 :(得分:1)

void main()应为int main(void)。无论哪本书或教程告诉你使用void main()都是由不熟悉C语言的人写的。

宏扩展后,main的正文相当于:

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

如果一元&运算符的操作数是一元*运算符的结果,则省略两个运算符(这在标准中明确说明),因此上述内容相当于:< / p>

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

这会获取int10并将其从int转换为unsigned int*

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

所以如果“内存地址10”的概念有意义,那么上面的可能会p设置为该地址。

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

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

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

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

将是这样做的方式。

答案 3 :(得分:0)

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