Come funziona sizeof con questa dereferenziazione di un puntatore ad array?


9

Qui ho un puntatore ptra array arrdi 4 numeri interi. ptrpunta all'intero array. ptr[0]oppure *ptrpunta al primo elemento dell'array, quindi l'aggiunta di 1 a ptr[0]fornisce l'indirizzo del secondo elemento dell'array.

Non riesco a capire perché l'utilizzo sizeof(ptr[0])fornisca la dimensione dell'intero array, 16 byte, non la dimensione del solo primo elemento, 4 byte (come ptr[0]indica il primo elemento dell'array).

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

La seconda riga non dovrebbe essere int *ptr = arr;? Ciò indicherebbe l'inizio (primo elemento) dell'array, che equivale a &arr[0].
Andreas Wenzel,

1
@AndreasWenzel La seconda riga non dovrebbe essere int *ptr = arr;? In realtà no. int (*ptr)[4]crea ptrcome puntatore a un array completo di quattro intvalori. Sintassi del puntatore del genere è necessaria per allocare dinamicamente array vero-multidimensionali. Gli "array bidimensionali" creati con malloc()loop nidificati e erroneamente descritti come array multidimensionali sono in realtà array 1-d di puntatori a più array 1-d. Vedi stackoverflow.com/questions/42094465/…
Andrew Henle,

Risposte:


6

OP: ptr[0]punta al primo elemento dell'array.

Digita confusione. ptr[0]è un array.

ptr è un puntatore all'array 4 di int .
ptr[0], come *ptrdifferisce il puntatore a un array .
sizeof(ptr[0])è la dimensione di un array.


Con sizeof(ptr[0]), ptr[0]non incorre in "un'espressione con il tipo '' puntatore al tipo '' che punta alla conversione dell'elemento iniziale dell'oggetto array. (c11dr §6.3.2.1 3). Con sizeof, ptr[0]è un array.


1
@ Abd-ElrahmanMohamed Accetto "Ma ptr [0] [0] è un numero intero non punta a un numero intero". "ptr [0] è l'indirizzo del primo elemento nell'array" non è vero.
chux - Ripristina Monica il

1
@ Abd-ElrahmanMohamed sì, i valori sono gli stessi ma i tipi sono diversi. ptr [0] ha tipo array e &ptr[0][0]ha int *tipo
Green Tree

1
@chux ptr[0](convertito implicitamente in int *) valuterebbe l'indirizzo del primo elemento int.
Green Tree,

1
@chux about sizeof - giusto, ho frainteso il contesto di quello che hai detto
Green Tree

1
@ Abd-ElrahmanMohamed Questo no. printf("someforamt", ptr[0] , ptr[0]+1)fa qualcosa di diverso da sizeof(ptr[0]). Il ptr[0]primo caso passa attraverso una conversione implicita. Con sizeof(ptr[0]), ptr[0]no.
chux - Ripristina Monica il

5

ptrqui è di tipo pointer to an array of 4 int elementse il tipo di array ha dimensione 16 sulla tua piattaforma (sizeof (int) * (numero di elemetns)).

Non riesco a capire perché l'uso di sizeof (ptr [0]) dia la dimensione dell'intero array a 16 byte, non la dimensione del solo primo elemento a 4 byte

perché il sistema di tipo C ha tipi di array. Qui entrambi arre *ptrce l'ha. Quello che dichiari di avere. Per ottenere sizeof int qui dovresti sizeof (ptr [0] [0]) - dove ptr [0] valuta l'array.


2

con int (*ptr)[4] = &arr ;hai un puntatore a un array di quattro numeri interi e puntando a arr.

ptrora punta a arr, come un doppio puntatore. Siamo in grado di accedere agli elementi di arrutilizzo ptr[0][x]in cui xpotrebbe essere 0a 4.

Lo sizeof(ptr[0])stesso vale persizeof(arr)


2

Per definizione, ptr[0]è lo stesso *(ptr + 0)che a sua volta è lo stesso di *ptr. Inoltre, ptrè inizializzato con &arr, così *ptrè *&arre questo è giusto arr. Si noti che l'immagazzinamento intermedio &arrin ptrnon non esegue alcun decadimento matrice, quindi l'equivalenza viene mantenuto e nessuna informazione tipo è persa.

Si noti che tutto ciò viene calcolato in fase di compilazione, solo per evitare questa insidie ​​aggiuntiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.