我不明白这行是做什么的:
((struct Example*) 0x10000)
我写了一个测试程序:
#include <stdio.h>
struct Elf{
int bla;
char bla2;
};
int main(){
struct Elf *elfPtr;
printf("Before casting: %p\n", elfPtr);
elfPtr = ((struct Elf *)0x10000);
printf("After casting: %p\n", elfPtr);
return 0;
}
输出结果为:
投射前:0xb776dff4
投射后:0x10000
这条线只能这样做吗?
elfPtr = 0x10000
答案 0 :(得分:5)
这会将指针设置为特定的常量值,这在具有虚拟内存管理的系统中是一个坏主意。
一个值得注意的例外是具有内存映射资源的嵌入式系统。在这样的系统中,硬件设计人员通常会保留一系列存储器地址以供替代使用,使程序员可以访问硬件寄存器,就好像它们是常规存储空间的一部分一样。
这是一个例子 * :
struct UART {
char data;
char status;
};
const UART *uart1 = 0xC0000;
const UART *uart2 = 0xC0020;
通过这种设置,嵌入式程序可以访问UART的寄存器,就好像它们是struct
的成员一样:
while (uart1->status & 0x02) {
uart1->data = 0x00;
}
<小时/> * UART代表Universal Asynchronous Receiver/Transmitter,这是一种常用于异步点对点通信的硬件。
答案 1 :(得分:2)
通常,为指针分配任意值是个坏主意。这就是为什么编译器不鼓励它,你需要添加强制转换来向编译器保证你知道你在做什么。
(您的代码将地址0x10000处的内存视为struct Elf
实例,至少在您的简单示例中,它不是。它甚至可能不是可读和/或可写内存,所以你'当你试图访问它时会崩溃。)
答案 2 :(得分:1)
该行elfPtr = ((struct Elf *)0x10000);
将使* Elf * 类型的指针指向由十六进制数0x10000(十进制65536)标识的内存地址
所以无论那个内存地址是什么,你都假设它是“Elf”类型
答案 3 :(得分:0)
使用该命令,您告诉编译器,地址0x10000处的数据是类型&#34; Elf&#34;的结构的实例,并将该类型的指针分配给该地址。
请注意,您还没有在该地址实例化该类型的任何结构,甚至没有为它预留内存,所以至少在尝试引用其成员时,如果不是分段错误,您将获得垃圾。< / p>
你真的应该避免使用绝对地址(除非是低级别的单片机编程),如果它甚至运行,它会产生不可移植的代码。