编译器如何解析结构成员的地址

How does a compiler resolve addresses of structure members?

本文关键字:地址 成员 结构 何解析 编译器      更新时间:2023-10-16

与数组相比,我对结构的内存组织有点困惑。数组元素可以通过数组中第一个元素的内存地址和所需索引的偏移量来访问。现在编译器如何计算结构成员的地址?

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;
}

编译器如何知道,在结构变量p中存储成员a的值的位置,以及编译器如何计算成员b的偏移量和地址

在第二种情况下,ptr包含对结构变量 pt 的引用。编译器如何知道成员的内存地址。

在编译时,编译器知道struct的大小及其成员的偏移量。为了您的struct name,编译器会计算出以下信息。

  1. struct name的大小
  2. 成员数据的布局
  3. a 的偏移量为零,b 的偏移量为非零。

struct name的布局可能如下所示:

  &lt--- 结构---------------->的大小   +-----------------+-----------------+   |                |                |   +-----------------+-----------------+   ^   |   PTR地址   ^                 ^   |                |   偏移 A (0) 偏移 B 的偏移量(非零)

给定指针指向struct name的地址,编译器确切地知道要偏移多少才能到达成员a,以及要偏移多少才能到达成员b

编译器知道结构成员的内存,因为编译器组织结构本身。它确定哪些位应该放在哪里。每当访问成员时,编译器都需要知道整个结构的定义,这就是原因,因此它知道位和片段的位置。至于实际的偏移量是什么,这取决于编译器想要如何做。

如果您需要知道偏移量,请在此处阅读有关offsetof的信息。

当你运行这个时,程序为p分配8个字节(4个用于整数,4个用于浮点数)。成员"a"的地址从 p 的地址开始。在第二种情况下,你直接将pt的地址分配给ptr,这意味着你将'a'的地址分配给ptr。

编译器如何知道成员的内存地址。

因为它首先分配了它们。这完全是编译器的决定。在符号表中,每个成员都附有其类型、大小以及结构

开始时的偏移量。

编译器使用的符号表包含有关结构中每个元素的信息,例如大小和数据类型。 Coz 结构是静态分配的,元素被打包在一起,它们的偏移量由每个元素大小确定。结构的地址是其第一个元素的地址

PTR->b=10.5; 是一种隐式指针算法,使用结构的地址和元素"A"的大小来确定元素"B"的位置。