与阵列相比,我对结构的内存组织有点困惑。数组元素可以通过数组中第一个元素的内存地址访问,并偏移到所需的索引。现在,编译器如何评估结构成员的地址?
struct name
{
int a;
float b;
};
int main()
{
struct name *ptr,pt,p;
p.a=4;
p.b=4.5;
ptr=&pt;
ptr->a=5;
ptr->b=10.5;
return 0;
}
编译器如何知道,在结构变量a
中存储成员p
的值的位置以及编译器如何评估成员b
的偏移量和地址
在第二种情况下,ptr
包含对结构变量pt
的引用。
编译器如何知道成员的内存地址。
答案 0 :(得分:6)
在编译时,编译器知道struct
的大小及其成员的偏移量。
对于struct name
,编译器会计算出以下信息。
struct name
a
的偏移量,为零,偏移量为b
,为非零。 struct name
的布局可能类似于:
<--- Size of struct ----------------> +-----------------+-----------------+ | | | +-----------------+-----------------+ ^ | Address of ptr ^ ^ | | offset of a (0) offset of b (non-zero)
给定指针指向struct name
的地址,编译器确切地知道要获得成员a
的偏移量以及要成员b
的偏移量。< / p>
答案 1 :(得分:2)
编译器知道结构成员的内存,因为编译器自己组织结构。它确定哪些位应该去哪里。每当访问一个成员时,编译器需要知道整个struct的定义,这就是原因,因此它知道这些碎片的位置。至于实际的偏移是什么,这取决于编译器想要如何做到。
如果您需要了解偏移量,请参阅offsetof
here。
答案 2 :(得分:1)
当你运行它时,程序为p分配8个字节(4表示int,4表示浮点数)。会员地址&#39; a&#39;从p的地址开始。在第二种情况下,您直接将pt的地址分配给ptr,这意味着您要分配&#39; a&#39;的地址。到ptr。
答案 3 :(得分:1)
编译器如何知道成员的内存地址。
因为首先分配它们。这完全是编译器的决定。在符号表中,每个成员都有它的类型,大小,以及从结构开始的偏移量。
答案 4 :(得分:1)
编译器使用的符号表包含有关结构中每个元素的信息,例如大小和数据类型。 coz结构是静态分配的,元素被打包在一起,它们的偏移量由每个元素大小决定。 struct的地址是其第一个元素的地址
ptr-&GT; B = 10.5;是一个隐式指针算法,使用struct的地址和元素的大小&#39; a&#39;确定元素的位置&#39; b&#39;。