32位处理器(更具体地说,它是在谈论数据总线的大小而不是寄存器的大小),这意味着一次读取和处理32位(4字节)的数据。
现在,考虑一个 int:
int a=10; //assuming 4 bytes
00000000 000000000 00000000 00001010
假设小端架构,它将被存储为:
------------------------------------------------------------------------
| 00001010 | 00000000 | 00000000 | 00000000 | <something_else>
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\--------------------------------------------------/
|
4 bytes processed together
在这种情况下,当处理器将读取要处理的数据时,它可以一次性处理整个整数(所有4个字节)(更严格地说是1个机器周期)
但是考虑存储相同整数的情况,
------------------------------------------------------------------------
|<something_else>| 00001010 | 00000000 | 00000000 | 00000000 |
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\------------------------------------------------------/
|
4 bytes processed together
在这种情况下,处理器需要 2 个机器周期来读取整数。
大多数架构总是尽量减少 CPU 周期。
因此,许多编译器首选内存中的第一种排列方式,从而强制执行对齐要求(填充)。
所以 4 字节 ints 存储在从 4 的倍数开始的地址中,chars 存储在 1 的倍数中,8 字节 doubles 存储在 8 的倍数中,8 字节 long long int 存储在 8 的倍数中等等上...
现在考虑你的结构
struct structure2
{
int id1; //assuming 4 byte int
char name; // 1byte
int id2; //4 byte
char c; // 1 byte
float percentage; //assuming 4 byte float
};
id1 将存储在内存中的某个地址(4 的起始倍数)中并占用 4 个字节。
name 将占用下一个字节。
现在如果 id2 被存储在下一个字节中,它将破坏上面的对齐规则。所以它会留下 3 个字节的填充并从地址开始存储,该地址是 4 的下一个倍数,需要 4 个字节。
对于 c 再次发生与 name 相同的事情。它占用下一个 1 字节并保留 3 字节的填充。
最后 百分比 被存储在接下来的 4 个字节中。
因此结构的总大小变为 20 字节。
一个更复杂的案例会说
struct mystructure
{
char a; //1 byte char
double b; // 8 byte double
int c; // 4 byte int
}
这里乍一看可能会说大小为 20 字节(char 为 1 字节 + 填充为 7 字节 + 双精度为 8 字节 + int 为 4 字节)。
但实际大小为 24 字节。
假设有人声明了这个结构的数组
struct mystructre arr[4];
这里(假设是 20 字节结构)虽然 arr[0] 是正确对齐的,但是如果你仔细检查你会发现 arr[1].b 没有对齐。所以在结构体末尾增加了 4 个字节的额外填充,使结构体大小成为其对齐的倍数。(每个结构体也有自己的对齐要求)。
因此总大小为 24 字节。
整数、长整数等的大小由编译器决定。编译器通常会处理处理器架构,但它可能会选择不这样做。
同样,是否使用填充由编译器决定。不填充被称为 packing。一些编译器具有允许打包的明确选项。
在 GCC(GNU C 编译器)中,您可以使用 __attribute__((__packed__)) 来完成,所以在下面的代码中
struct __attribute__((__packed__)) mystructure2
{
char a;
int b;
char c;
};
mystructure2 的大小为 6 个字节,因为明确请求打包结构。此结构将处理速度较慢。
您现在可能已经自己弄清楚了,在 64 位处理器中会发生什么,或者如果 int 的大小不同。