Inizializzazione da avviso di tipo di puntatore incompatibile durante l'assegnazione a un puntatore

Inizializzazione da avviso di tipo di puntatore incompatibile durante l'assegnazione a un puntatore


GCC mi dà un avviso "Inizializzazione da tipo di puntatore incompatibile" quando uso questo codice (sebbene il codice funzioni correttamente e faccia ciò che dovrebbe fare, ovvero stampare tutti gli elementi dell'array).


#include <stdio.h>
int main(void)
{
int arr[5] = {3, 0, 3, 4, 1};
int *p = &arr;
printf("%p\n%p\n\n", p);
for (int a = 0; a < 5; a++)
printf("%d ", *(p++));
printf("\n");
}

Tuttavia, non viene fornito alcun avviso quando utilizzo questo bit di codice


int main(void)
{
int arr[5] = {3, 0, 3, 4, 1};
int *q = arr;
printf("%p\n%p\n\n", q);
for (int a = 0; a < 5; a++)
printf("%d ", *(q++));
printf("\n");
}

L'unica differenza tra questi due frammenti è che assegno *p =&arr e *q =arr .



  • Che cos'è esattamente la differenza che sta facendo &?

  • E perché il codice viene eseguito e fornisce lo stesso identico output in entrambi i casi?


Risposte:



  • &arr fornisce un puntatore array , un tipo di puntatore speciale int(*)[5] che punta all'array nel suo insieme.

  • arr , quando scritto in un'espressione come int *q = arr; , "decade" in un puntatore al primo elemento. Completamente equivalente a int *q = &arr[0];


Nel primo caso provi ad assegnare un int(*)[5] a un int* . Questi sono tipi di puntatore incompatibili, da qui il messaggio di diagnostica del compilatore.


A quanto pare, il puntatore all'array e il puntatore int al primo elemento avranno molto probabilmente la stessa rappresentazione e lo stesso indirizzo internamente. Ecco perché il primo esempio "funziona" anche se non è corretto C.