Como o sizeof funciona com essa desreferenciação de um ponteiro para array?

9

Aqui eu tenho um ponteiro ptrpara matriz arrde 4 números inteiros. ptraponta para toda a matriz. ptr[0]ou *ptraponta para o primeiro elemento da matriz, portanto, adicionar 1 a ptr[0]fornece o endereço do segundo elemento da matriz.

Não consigo entender por que usar sizeof(ptr[0])fornece o tamanho de toda a matriz, 16 bytes, não o tamanho apenas do primeiro elemento, 4 bytes (como ptr[0]pontos do primeiro elemento na matriz).

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16
Abd-Elrahman Mohamed
fonte
A segunda linha não deveria ser int *ptr = arr;? Isso faria apontar para o início (primeiro elemento) da matriz, que é equivalente a &arr[0].
Andreas Wenzel
11
@AndreasWenzel Não deveria ser a segunda linha int *ptr = arr;? Na verdade não. int (*ptr)[4]cria ptrcomo um ponteiro para uma matriz completa de quatro intvalores. Sintaxe de ponteiro assim é necessária para alocar dinamicamente matrizes multidimensionais verdadeiras. As "matrizes bidimensionais" criadas com malloc()loops aninhados e descritas incorretamente como matrizes multidimensionais são na verdade matrizes 1-d de ponteiros para várias matrizes 1-d. Veja stackoverflow.com/questions/42094465/…
Andrew Henle

Respostas:

6

OP: ptr[0]aponta para o primeiro elemento na matriz.

Digite confusão. ptr[0]é uma matriz.

ptr é um ponteiro para a matriz 4 de int .
ptr[0], como *ptradia o ponteiro para uma matriz .
sizeof(ptr[0])é o tamanho de uma matriz.


With sizeof(ptr[0]), ptr[0]não incorre em "uma expressão com o tipo '' ponteiro para o tipo '' que aponta para o elemento inicial da conversão do objeto da matriz". (c11dr §6.3.2.1 3). With sizeof, ptr[0]é uma matriz.

chux - Restabelecer Monica
fonte
11
@ Concordo Abd-ElrahmanMohamed "Mas ptr [0] [0] é um número inteiro que não aponta para número inteiro". "ptr [0] é o endereço do primeiro elemento da matriz" não é verdadeiro.
chux - Restabelece Monica
11
@ Abd-ElrahmanMohamed sim, os valores são os mesmos, mas os tipos são diferentes. ptr [0] possui um tipo de matriz e &ptr[0][0]tem o int *tipo
Green Tree
11
@chux ptr[0](implicitamente convertido em int *) avaliaria o endereço do primeiro elemento int.
Green Tree
11
@chux sobre sizeof - bem, eu não entendi o contexto do que você disse
Green Tree
11
@ Abd-ElrahmanMohamed Isso não acontece. printf("someforamt", ptr[0] , ptr[0]+1)faz algo diferente de sizeof(ptr[0]). O ptr[0]primeiro caso passa por uma conversão implícita. Com sizeof(ptr[0]), ptr[0]não.
chux - Restabelece Monica
5

ptraqui é do tipo pointer to an array of 4 int elementse o tipo de matriz tem tamanho 16 na sua plataforma (sizeof (int) * (número de elemetns)).

Não consigo entender por que usar sizeof (ptr [0]) fornece ao tamanho de toda a matriz 16 bytes e não ao tamanho do primeiro elemento 4 bytes

porque o sistema do tipo C possui tipos de matriz. Aqui ambos arre *ptrtem. O que você declara ter. Para obter sizeof int aqui, você deve sizeof (ptr [0] [0]) - onde ptr [0] é avaliado como array.

Árvore verde
fonte
2

com int (*ptr)[4] = &arr ;você tem um ponteiro para uma matriz de quatro números inteiros e apontando para arr.

ptragora está apontando para arr, como um ponteiro duplo. Podemos acessar elementos de arrusar ptr[0][x], onde xpoderia ser 0para 4.

Então sizeof(ptr[0])é o mesmo quesizeof(arr)

rsonx
fonte
2

Por definição, ptr[0]é o mesmo *(ptr + 0)que, por sua vez, é o mesmo que *ptr. Além disso, ptré inicializado com &arr, assim *ptré *&arre isso é justo arr. Note-se que o armazenamento intermédio de &arrem ptrque não executa qualquer deterioração matriz, de modo que a equivalência é mantida e nenhuma informação tipo é perdida.

Observe que tudo isso é calculado em tempo de compilação, apenas para evitar essa armadilha adicional.

Ulrich Eckhardt
fonte