以64位的CPU为例进行简单说明。
char 1字节
int 4字节
long 8字节
内存寻址
疑问:
在学习C语言结构体时提到了内存对齐,有如下说法:

现在假设内存寻址读取时可以从任意地址开始,结果将会如下所示:

所以,以4的倍数进行内存寻址,可以以最快的速度寻址:不遗漏一个字节,也不会重复对一个字节寻址
内存对齐
比方说如下代码:
#include <stdio.h>
int main() {
char str;
int num;
printf("%o\n", &str);
printf("%o\n", &num);
return 0;
}
假设内存段长这样:


str 的内存地址:30377437
num 的内存地址:30377430
可见,明显相差了 7 个地址

从上图可以看出,已经发生了所谓的“内存对齐”的现象。
首先来了解一下数据总线和地址总线的概念。

数据总线通俗来讲就是传输数据的线路,而CPU到内存之间如果是64位操作系统的话就会有64根数据总线相连,32位的话则是32根;而每一根数据总线所能传输的就是0和1两种,64根数据总线代表着64个bit位,64bit = 8byte;所以,每次CPU能读取的数据就是8个字节大小,这点很重要。
地址总线同样的,64根地址总线连接CPU和内存,也就可以代表有2的64次方个地址。
先假设每一个类型的变量都一个紧挨着一个的在内存中存储,那么,如果按照上述代码的话,存储的时候,char会在“编号0”地址上,int会在“编号1”地址上,当读取的时候,一次性读取8字节大小数据,只需要读取一遍就可以把两个变量都能内存中读取出来,这样看来不是也挺好的吗?
现在再来看另外一段代码:
#include <stdio.h>
int main() {
char str;
long num;
printf("%o\n", &str);
printf("%o\n", &num);
return 0;
}
这一段代码中,我们把原先的int类型的num改成了long类型的,long类型在64位操作系统中占据8字节大小。
想象一下,按照一个紧挨着一个的话,会是怎样?


那如果采用“内存对齐”填充的方式呢?再来看一张图:

这时候还不算完,下面再来看一段代码吧:
#include <stdio.h>
int main() {
long num;
int num1;
char str;
printf("%o\n", &num);
printf("%o\n", &num1);
printf("%o\n", &str);
return 0;
}
上述代码中增加了一个int类型,并且声明顺序是按照内存大小从大到小的,与之前的代码生命顺序相反,我们来看看结果:
num 的内存地址:30377434
num1 的内存地址:30377430
str 的内存地址:30377427
可以看到,long和int相差7, int和char相差4,存储结构类似下图:

所以,在定义数据时,最好是按照内存大小从大到小来进行声明
以上理解并不全面,日后补充,都不是最终定论。