我目前正在阅读《理解使用 C 指针》一书,我偶然发现了以下示例:
int (*(arr1[])) = {(int[]){0,1,2}, (int[]) {3,4,5}, (int[]){6,7,8}}
作者随后展示了 arr1[0][0]...arr1[2][2] 的内存布局,可以看到元素存储在连续的区域中。
关于这个例子我有两个问题:
int *(arr1[]) = ...
我将其理解为:arr1 被声明为包含指向 int 的指针的数组。
a = {...}
并列出以逗号分隔的元素。现在,在前面的示例中,arr1 的元素应该是指针(除非我对声明的理解是错误的)。因此,我认为对于第一个成员来说
int *(arr1[])= {(int[]){0,1,2},...
创建包含 0,1,2 的数组,然后返回其地址(这对应于转换为 int[])并将其用作第一个指针的值。然而,如果这是真的,那么数字 0,1,2 将位于与数字 3,4,5 可能独立的内存段中。
有人可以进一步解释一下吗?
声明
int (*(arr1[]))
中不需要任何括号。使用 int *arr1[]
是等效的并且更具可读性。
对于具有连续地址的复合文字,则不要求如此。虽然在同一范围内声明的复合文字(和命名变量)具有相同一般范围内的地址是有意义的,但编译器可以随意排列它们。
当我尝试创建给定的数组并打印每个元素的地址时,我得到以下结果:
0x7ffdf47f3880
0x7ffdf47f3890
0x7ffdf47f38a0
因此,在这种特殊情况下,复合文字的地址不断增加,但彼此并不相邻。每个字节之间有 4 个字节,因此不连续。