我目前正在阅读《理解和使用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的指针的array.

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

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

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

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

有人能对此作进一步的解释吗?

推荐答案

声明int (*(arr1[]))中的括号都不是必需的.使用int *arr1[]将是等效的,并且更具可读性.

对于具有连续地址的复合文字,不要求必须是这种情况.虽然在同一作用域中声明的复合文字(和命名变量)具有相同一般范围内的地址是有意义的,但编译器可以随意安排它们.

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

0x7ffdf47f3880
0x7ffdf47f3890
0x7ffdf47f38a0

因此,在此特定情况下,复合文字具有递增的地址,但彼此不相邻.每个字节之间有4个字节,因此不是连续的.

C++相关问答推荐

Bison解析器转移/减少冲突

我可以动态分配具有空类型函数的矩阵吗?

为什么我得到更多的256假阳性在PKZIP解密密钥验证?

C:scanf(%d&q;,...)输入只有一个减号

如何使用低级C++写出数值

在没有动态内存分配的情况下,用C语言最快地将各种数组复制到单个较大的数组中

非正规化边缘毛刺

1处的解析器错误:yacc语法的语法错误

对重叠字符串使用MemMove

防止规范模式在C++中 echo 特殊字符

在另一个函数中使用realloc和指针指向指针

为什么双精度d=flt_max+flt_max;在c语言中得到inf的结果

等同于铁 rust 的纯C语言S未实现!()宏

如何在C中使数组变量的值为常量?

Fprintf正在写入多个 struct 成员,并且数据过剩

使用正则表达式获取字符串中标记的开始和结束

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

WSASocket在哪里定义?

C struct 中的冒泡排序