注意,我发现在图像中我忘记计算 0x000000 地址了,抱歉。
这是一个很好的问题,如果我解释你已经熟悉的概念,我很抱歉,但以防万一。
首先,遗憾的是,与大多数事情一样,这取决于。我这样说是因为 64 位在使用之间可能并不真正意味着相同,这是因为它主要可以指数据总线,或地址总线,或两者兼而有之。这取决于您的体系结构,如果您使用的是计算机,那么很可能您在地址总线和数据总线上都使用 32 位。如果您正在使用 MCU,那么它将在很大程度上取决于 MCU 及其架构,也许您的寻址将是 16 位,但它是数据 32。
这样,让我们专注于地址总线,有一个 32 位地址总线,意味着你可以去 2^32 个不同的地址,现在我想这就是你混淆的地方,每个地址实际上是一个字节,那就是为什么 32 位计算机限制为 4GB 内存,因为 2^32 = 4,294,967,296。如果每个都是一个字节,那么就是 4GB。
现在,内存中每个字的长度由数据总线定义,正如我们所说,最有可能的是它也是一个 32 位,所以,这将允许我们容纳 4 个字节,因此,每个字将是由 4 个字节组成。所以在这种情况下,我们的 ram“网格”看起来像这样。快速注意,现在从未真正使用过内存寻址。使用字节寻址,字不需要像行一样开始/结束。
现在,填充会发生什么,首先,所有数据类型在 C 中都有一个本机大小,这个大小还取决于你的架构,一些数据类型使用一个字(4 个字节),一些使用2 个字(8 个字节)和一些 1 个字节。请记住,字长取决于数据总线的大小,在这种情况下,32 位数据总线 = 32/8 = 4 个字。 char 类型只使用一个字节。当您编译和运行时,处理器开始分配内存并跟踪所有内容,例如,在这种情况下,您的填充无关紧要,处理器知道它是空闲的,并会在需要时分配一些东西。还要记住,单词没有定义为内存中的一行,只要它们是连续的,cpu 可以要求 4 个连续字节,可能使用上图作为参考,从 0x00...02 到 0x00... 05.
例如,您可以将 b 存储在 0x0000,b 存储在 0x0001,a 存储在 0x0002,然后您可以存储 0x0003-0x0006 的有符号整数(在现代计算机中通常为 4 个字节)。 cpu 会跟踪整数在 0x0003-0x0006 中,c 在 0x0001 中等等,并且你的结构是从 0x0000 到 0x0002