¿Cómo funciona sizeof con esta desreferenciación de un puntero a la matriz?

9

Aquí tengo un puntero ptra una matriz arrde 4 enteros. ptrapunta a toda la matriz. ptr[0]o *ptrapunta al primer elemento de la matriz, por lo que sumar 1 a ptr[0]da la dirección del segundo elemento de la matriz.

No puedo entender por qué usar sizeof(ptr[0])da el tamaño de toda la matriz, 16 bytes, no el tamaño del primer elemento, 4 bytes, (como ptr[0]apunta al primer elemento de la matriz).

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16
Abd-Elrahman Mohamed
fuente
¿No debería ser la segunda línea int *ptr = arr;? Eso lo haría apuntar al inicio (primer elemento de) la matriz, que es equivalente a &arr[0].
Andreas Wenzel
1
@AndreasWenzel ¿No debería ser la segunda línea int *ptr = arr;? En realidad no. int (*ptr)[4]crea ptrcomo un puntero a una matriz completa de cuatro intvalores. Una sintaxis de puntero como esa es necesaria para asignar dinámicamente matrices multidimensionales verdaderas. Las "matrices bidimensionales" creadas con malloc()bucles anidados y descritas erróneamente como matrices multidimensionales son realmente matrices 1-d de punteros a múltiples matrices 1-d. Ver stackoverflow.com/questions/42094465/…
Andrew Henle

Respuestas:

6

OP: ptr[0]apunta al primer elemento de la matriz.

Escriba confusión. ptr[0]es una matriz

ptr es un puntero a la matriz 4 de int .
ptr[0], como *ptrdefiende el puntero a una matriz .
sizeof(ptr[0])es el tamaño de una matriz.


Con sizeof(ptr[0]), ptr[0]no incurre en la conversión de "una expresión con tipo '' puntero a tipo '' que apunta al elemento inicial del objeto de matriz". (c11dr §6.3.2.1 3). Con sizeof, ptr[0]es una matriz.

chux - Restablece a Monica
fuente
1
@ Abd-ElrahmanMohamed De acuerdo "Pero ptr [0] [0] es un entero, no apunta a un entero". "ptr [0] es la dirección del primer elemento en la matriz" no es cierto.
chux - Restablece a Monica el
1
@ Abd-ElrahmanMohamed sí, los valores son iguales pero los tipos son diferentes. ptr [0] tiene tipo de matriz y &ptr[0][0]tiene int *tipo
Green Tree
1
@chux ptr[0](convertido implícitamente a int *) evaluaría la dirección del primer elemento int.
Green Tree
1
@chux sobre sizeof - correcto, no entendí el contexto de lo que dijiste
Green Tree el
1
@ Abd-ElrahmanMohamed Eso no. printf("someforamt", ptr[0] , ptr[0]+1)hace algo diferente a sizeof(ptr[0]). En ptr[0]el primer caso pasa por una conversión implícita. Con sizeof(ptr[0]), ptr[0]no lo hace.
chux - Restablece a Monica
5

ptraquí es de tipo pointer to an array of 4 int elementsy el tipo de matriz tiene un tamaño 16 en su plataforma (sizeof (int) * (número de elementos)).

No puedo entender por qué usar sizeof (ptr [0]) da el tamaño de toda la matriz de 16 bytes, no el tamaño del primer elemento de 4 bytes

porque el sistema de tipo C tiene tipos de matriz. Aquí ambos arry lo *ptrtiene. Lo que declaras que tienes. Para obtener sizeof int aquí debe sizeof (ptr [0] [0]) - donde ptr [0] se evalúa como matriz.

Árbol verde
fuente
2

con int (*ptr)[4] = &arr ; usted tiene un puntero a una matriz de cuatro enteros y apunta a arr.

ptrahora apunta a arr, como un puntero doble. Podemos acceder a elementos del arruso de ptr[0][x]wherex podría ser 0a 4.

Entonces sizeof(ptr[0])es igual quesizeof(arr)

rsonx
fuente
2

Por definición, ptr[0]es lo mismo *(ptr + 0)que a su vez es lo mismo que *ptr. Además, ptrse inicializa con &arr, así *ptres *&arry eso es justo arr. Tenga en cuenta que el almacenamiento intermedio de &arrin ptrhace no realiza ninguna descomposición de matriz, por lo que la equivalencia se mantiene y no información de tipo se pierde.

Tenga en cuenta que todo esto se calcula en tiempo de compilación, solo para evitar este escollo adicional.

Ulrich Eckhardt
fuente