#define address (*((unsigned int *)10))
void main()
{
unsigned int *p;
p = &(address);
}
'p'的值为10。 如何评估上述表达式? 是不是从内心最大支撑到最外面的支撑? 但如果是这样那么'&'有一个没有意义的左值。 我知道它被转换为& *(10),其评估为10。
答案 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;
这会获取int
值10
并将其从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。