用复合文字数组初始化的指针数组

问题描述 投票:0回答:1

我目前正在阅读《理解使用 C 指针》一书,我偶然发现了以下示例:

int (*(arr1[])) = {(int[]){0,1,2}, (int[]) {3,4,5}, (int[]){6,7,8}}

作者随后展示了 arr1[0][0]...arr1[2][2] 的内存布局,可以看到元素存储在连续的区域中。

关于这个例子我有两个问题:

  1. 不明白为什么arr1的声明中第一个括号是必须的,即和下面的声明有区别吗:
int *(arr1[]) = ...

我将其理解为:arr1 被声明为包含指向 int 的指针的数组。

  1. 我真的不明白为什么这个例子会产生一个连续的块。因为: 如果我初始化一个数组,我会写
a = {...}

并列出以逗号分隔的元素。现在,在前面的示例中,arr1 的元素应该是指针(除非我对声明的理解是错误的)。因此,我认为对于第一个成员来说

int *(arr1[])= {(int[]){0,1,2},...

创建包含 0,1,2 的数组,然后返回其地址(这对应于转换为 int[])并将其用作第一个指针的值。然而,如果这是真的,那么数字 0,1,2 将位于与数字 3,4,5 可能独立的内存段中。

有人可以进一步解释一下吗?

c pointers
1个回答
0
投票

声明

int (*(arr1[]))
中不需要任何括号。使用
int *arr1[]
是等效的并且更具可读性。

对于具有连续地址的复合文字,则不要求如此。虽然在同一范围内声明的复合文字(和命名变量)具有相同一般范围内的地址是有意义的,但编译器可以随意排列它们。

当我尝试创建给定的数组并打印每个元素的地址时,我得到以下结果:

0x7ffdf47f3880
0x7ffdf47f3890
0x7ffdf47f38a0

因此,在这种特殊情况下,复合文字的地址不断增加,但彼此并不相邻。每个字节之间有 4 个字节,因此不连续。

© www.soinside.com 2019 - 2024. All rights reserved.