È possibile inizializzare un puntatore C a NULL?
TL; DR Sì, molto.
L' affermazione effettiva fatta sulla guida si legge come
D'altra parte, se si utilizza solo l'assegnazione iniziale singola int *my_int_ptr = 2;, il programma tenterà di riempire il contenuto della posizione di memoria indicata da my_int_ptrcon il valore 2. Poiché my_int_ptrè pieno di spazzatura, può essere qualsiasi indirizzo. [...]
Ebbene, essi sono sbagliato, hai ragione.
Per la dichiarazione, ( ignorando, per ora, il fatto che il puntatore alla conversione di numeri interi è un comportamento definito dall'implementazione )
int * my_int_ptr = 2;
my_int_ptrè una variabile (di tipo puntatore a int), ha un indirizzo proprio (tipo: indirizzo del puntatore a numero intero), stai memorizzando un valore di 2in quell'indirizzo .
Ora, my_int_ptressendo un tipo di puntatore, possiamo dire, punta al valore di "tipo" nella posizione di memoria indicata dal valore contenuto my_int_ptr. Quindi, stai essenzialmente assegnando il valore della variabile del puntatore, non il valore della posizione di memoria a cui punta il puntatore.
Quindi, per concludere
char *x=NULL;
inizializza la variabile del puntatore xsu NULL, non il valore nell'indirizzo di memoria a cui punta il puntatore .
Questo è lo stesso di
char *x;
x = NULL;
Espansione:
Ora, essendo rigorosamente conforme, un'affermazione come
int * my_int_ptr = 2;
è illegale, in quanto implica la violazione dei vincoli. Per essere chiari,
my_int_ptr è una variabile puntatore, tipo int *
- una costante intera,
2ha tipo int, per definizione.
e non sono tipi "compatibili", quindi questa inizializzazione non è valida perché viola le regole dell'assegnazione semplice, menzionate nel capitolo §6.5.16.1 / P1, descritte nella risposta di Lundin .
Nel caso qualcuno sia interessato a come l'inizializzazione è collegata a semplici vincoli di assegnazione, citando C11, capitolo §6.7.9, P11
L'inizializzatore per uno scalare deve essere una singola espressione, facoltativamente racchiusa tra parentesi graffe. Il valore iniziale dell'oggetto è quello dell'espressione (dopo la conversione); si applicano gli stessi vincoli e conversioni di tipo dell'assegnazione semplice, considerando il tipo dello scalare come versione non qualificata del suo tipo dichiarato.
int *x = whatever;fa e cosaint *x; *x = whatever;fa.int *x = whatever;effettivamente si comporta comeint *x; x = whatever;, no*x = whatever;.