3. 一维数组的内存结构
要真正了解 C 语言,你要了解每一种类型的内存结构。这一节我们来介绍一下一维数组的内存结构。
以整数类型的一维数组为例,比如我们声明如下的数组:
int myarr[3] = {100, 200, 300};
我们通过 sizeof 运算符计算 sizeof(myarr) 得到数组占用的内存数是 12 个字节。那这三个整数又是如何排列的呢?
我们先来说结论。
- 数组的起始地址就是第一个数据元素的地址。
- 数组中每个数据元素的起始地址是:
数组的起始地址 + 数据元素类型占用的字节数 * 索引。
我们通过取地址运算符,对上述数组,以及数组中数据元素依次取地址,这样就可以得到每个数据在内存中的地址了。让我们一起来写程序验证吧。
示例程序
// filename: 1d_array_momory.c
#include <stdio.h>
int main(int argc, char *argv[]) {
int myarr[3] = {100, 200, 300};
printf("&myarr: %p\n", &myarr); // 获取数组的起始地址
printf("&myarr[0]: %p\n", &myarr[0]); // 第一个数据元素的起始地址
printf("&myarr[1]: %p\n", &myarr[1]); // 第二个数据元素的起始地址
printf("&myarr[2]: %p\n", &myarr[2]); // 第三个数据元素的起始地址
printf("&myarr[3]: %p\n", &myarr[3]); // 第三个数据元素的末尾地址
return 0;
}
运行结果如下:
weimingze@mzstudio:~$ gcc -o 1d_array_momory 1d_array_momory.c
weimingze@mzstudio:~$ ./1d_array_momory
&myarr: 0x7ffdde2519dc
&myarr[0]: 0x7ffdde2519dc
&myarr[1]: 0x7ffdde2519e0
&myarr[2]: 0x7ffdde2519e4
&myarr[3]: 0x7ffdde2519e8
由此可见, 数组 myaddr 的内存结构如下图所示
myarr[0] myarr[1] myarr[2]
----+----+----+----+----+----+----+----+----+----+----+----+----+----
... | 100 | 200 | 300 | ...
----+----+----+----+----+----+----+----+----+----+----+----+----+----
^ ^ ^ ^
| &myarr[0] | &myarr[1] | &myarr[2] | &myarr[3]
| &myarr | | |
0x7ffdde2519dc 0x7ffdde2519e0 0x7ffdde2519e4 0x7ffdde2519e8
(数组的起始地址)
练习:
声明一个 double 类型的数组,通过打印地址的方式来分析数组的内存结构并在纸上画图说明。