sizeof如何与对数组的指针取消引用一起工作?


9

在这里,我有一个指向4个整数的ptr数组arr的指针。ptr指向整个数组。ptr[0]*ptr指向数组的第一个元素,因此加1即可ptr[0]得出数组第二个元素的地址。

我不明白为什么使用sizeof(ptr[0])给出整个数组的大小16个字节,而不是第一个元素的大小4个字节(ptr[0]指向数组中第一个元素)。

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16

第二行不应该int *ptr = arr;吗?这将使其指向数组的开始(第一个元素),它等效于&arr[0]
安德烈亚斯·温泽尔

1
@AndreasWenzel 第二行不应该int *ptr = arr;吗? 其实没有 int (*ptr)[4]创建ptr一个指向四个int值的完整数组的指针。像这样的指针语法对于动态分配真实多维数组是必需的。用嵌套malloc()循环创建并被错误描述为多维数组的“二维数组” 实际上是指向多个1维数组的指针的1维数组。参见stackoverflow.com/questions/42094465/…–
安德鲁·亨利

Answers:


6

OP:ptr[0]指向数组中的第一个元素。

类型混乱。 ptr[0]是一个数组。

ptr 是一个指向int数组4的指针
ptr[0]就像*ptr指针指向数组一样
sizeof(ptr[0])是数组的大小。


使用时sizeof(ptr[0])ptr[0]不会引起“指向数组对象的初始元素的类型为“指向类型的指针”的表达式”转换。(c11dr§6.3.2.13)。使用sizeofptr[0]是一个数组。


1
@ Abd-ElrahmanMohamed同意“但是ptr [0] [0]是一个整数,并不指向整数”。“ ptr [0]是数组中第一个元素的地址”不正确。
chux-恢复莫妮卡

1
@ Abd-ElrahmanMohamed是的,值相同,但类型不同。ptr [0]具有数组类型,并且&ptr[0][0]具有int *类型
Green Tree

1
@chux ptr[0](隐式转换为int *)将求值为第一个int元素的地址。
绿树

1
@chux关于sizeof-对,我误解了您所说的内容
Green Tree

1
@ Abd-ElrahmanMohamed事实并非如此。 printf("someforamt", ptr[0] , ptr[0]+1)做一些与...有所不同的事情sizeof(ptr[0])。该ptr[0]通过转换inplicit在第一种情况下前进。使用sizeof(ptr[0])ptr[0]不使用。
chux-恢复莫妮卡

5

ptr这是类型pointer to an array of 4 int elements,数组类型在您的平台上大小为16(sizeof(int)*(elemetns的数量))。

我不明白为什么使用sizeof(ptr [0])会使整个数组的大小为16个字节,而不仅仅是第一个元素的大小为4个字节

因为C类型系统具有数组类型。在这里arr*ptr都有。您声明拥有的东西。要在此处获取sizeof int,您应该选择sizeof(ptr [0] [0])-其中ptr [0]的值为数组。


2

int (*ptr)[4] = &arr ;您有一个指向四个整数的数组的指针,并指向arr。

ptr现在指向arr,就像一个双指针。我们可以访问的内容arr使用ptr[0][x],其中x可能是04

因此sizeof(ptr[0])sizeof(arr)


2

根据定义,ptr[0]是相同的*(ptr + 0)这又是一样的*ptr。此外,ptr被初始化&arr,所以*ptr*&arr那就是arr。注意的中间存储&arrptr没有执行任何阵列衰变,所以等价被保持并且没有类型信息丢失。

请注意,所有这些都是在编译时计算的,只是为了避免这种额外的陷阱。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.