Cos’è un puntatore nullo e cos’è un puntatore nullo?

Quindi stavo passando alcune domande di intervista e mi sono imbattuto in uno sui puntatori nulli e nulli , che afferma:

un puntatore senza tipo di ritorno è chiamato puntatore nullo. Potrebbe essere qualsiasi tipo di datatype.

Questo mi ha confuso completamente! Sembra vuoto e nullo potrebbe essere usato in modo intercambiabile secondo questa domanda, e non credo che sia corretto. Ho ritenuto nullo essere un tipo di ritorno e null per essere un valore. Ma io sono solo un novellino e non sono sicuro di avere ragione.

Si prega di esprimere le vostre opinioni su cosa sia un puntatore nullo e un puntatore vuoto. Non sto cercando la differenza tra null e void.

I due concetti sono ortogonali:

  1. Un puntatore vuoto, ( void * ) è un puntatore non elaborato in una posizione di memoria.
  2. Un puntatore nullo è un puntatore speciale che non punta a nulla, per definizione. Può essere un puntatore a qualsiasi tipo, vuoto o altro.

Un puntatore vuoto può essere nullo o no:

 void *void_ptr1 = nullptr; void *void_ptr2 = malloc(42); void *void_ptr3 = new Foo; // void * can point to almost anything void *void_ptr4 = (char*)void_ptr3 + 1; // even somewhere inside an object 

Un puntatore non vuoto può anche essere nullo o no:

 Foo *f = nullptr; Foo *g = new Foo; 

Semplicemente dimenticati di quella risposta. Una citazione dal tuo link:

“un puntatore senza tipo di ritorno è chiamato puntatore nullo.”

Questo è talmente sbagliato . Il tipo di ritorno di un puntatore? VERAMENTE? Questa è una ctriggers fonte …

void* è un tipo di puntatore universale perché qualsiasi tipo di puntatore (ad eccezione del puntatore su const e / o volatile) può essere convertito implicitamente in void* . In altre parole, puoi assegnare qualsiasi puntatore a una variabile di tipo void* . Un puntatore nullo è un valore puntatore 0

Il tipo di void in generale significa che non vengono fornite informazioni sul tipo.

Bisogna sempre ricordare che un puntatore trasmette due informazioni: il tipo di dati puntati ( int , double , …), che specifica come interpretarlo, e l’ indirizzo dei dati a cui punta, che specifica dove puoi ottenere il valore reale dei dati puntati.

Le informazioni sul tipo sono nel tipo del puntatore ( double * , int * , …), mentre l’indirizzo dei dati è il valore effettivo contenuto nella variabile pointer.

Quindi, un puntatore void ( void * ) è un puntatore che non specifica alcuna informazione sul tipo. Ti dice dove sono i dati, ma non ti dice come interpretarli. Sai che a quell’indirizzo c’è qualcosa, ma non sai se è un int , un double o una schiera di mucche volanti. Per utilizzare effettivamente tali dati, devi ottenere informazioni di tipo su di essi in qualche altro modo (ad esempio con qualche altro parametro magico), lanciare quel puntatore su un normale tipo di puntatore e usarlo come al solito.

void * è spesso usato in C per fornire un qualche tipo di supporto alla programmazione generica; vedere ad esempio la qsort libreria qsort C.

Un puntatore NULL , invece, è un puntatore che non punta a nulla. In questo caso, sono presenti le informazioni sul tipo del puntatore in generale, ma è l’indirizzo dei dati puntati che manca. Certo, è ansible avere un void * che è NULL .

Esempio rapido (supponendo che v sia dichiarato come double v; ):

  Type information present +----------------------+----------------------+ | ✔ | ✘ | +---+----------------------+----------------------+ pc | | | | voo | ✔ | double * ptr = &v; | void * ptr = &v; | ain | | | | lnt +---+----------------------+----------------------+ ite | | | | den | ✘ | double * ptr = NULL; | void * ptr = NULL; | dt | | | | +---+----------------------+----------------------+ 

Curiosità : NULL , almeno nello standard attuale, è garantito che sia 0.

In altre aree della lingua, void è sempre usato per specificare la mancanza di tipo. Usarlo come valore di ritorno (nota: sto parlando di void , not void * ) significa che la funzione non restituisce alcun valore, e lanciare un’espressione a void è un modo elegante per scartare un valore (stai segnalando a il compilatore e ad altri programmatori che sei consapevole che non stai utilizzando un determinato valore).

Per favore, dicci: qual è la differenza:

  • tra il serbatoio del gas e la situazione di assenza di gas
  • tra cookie jar e no-cookies
  • tra “soldi” e “tasche vuote”

Se vieni con questi, sarai in grado di cogliere null vs void * dillema.

vuoto è un non-tipo. null è un non valore.

Ecco alcune differenze rispetto all’aritmetica del puntatore:

Deriva dal fatto che il vuoto è un tipo incompleto.

 void *vp; vp++; // error, incomplete type vp += 2; // same error void *p = 0; p++; // still same error int *p = 0; p++; // well-formsd program, but UB ($5.6/5) 

L’articolo collegato è semplicemente sbagliato. La sua prima frase:

un puntatore senza tipo di ritorno è chiamato puntatore nullo

sta facendo scattare tutti i tipi di allarmi per me. Questo è un pezzo di scrittura altamente confuso.

Sei quasi corretto. “Pointer to void” è un tipo (non un “tipo di ritorno”). I valori di qualsiasi tipo possono essere restituiti da funzioni e quindi essere (il tipo di funzione) restituito.

Un puntatore nullo è un puntatore che, indipendentemente dal suo tipo, punta verso l’object nullo, che non è un object valido che può essere creato. Si può dire che un puntatore nullo punta a “nulla”.

Anche un puntatore al vuoto può essere nullo;

 void *nothing = 0; 

è un codice perfettamente valido e dice solo che questo puntatore è in grado di puntare un object non tipizzato, ma al momento non lo è.

il puntatore nullo punta a 0x000000 (che non è corretto per accedere al puntatore), mentre il puntatore vuoto è un puntatore corretto per un tipo non specificato ( void * ). Tuttavia, il puntatore void può essere un puntatore nullo, ma in seguito il non riferimento del puntatore genera un errore.

Un void *ptr è il puntatore che può essere utilizzato per puntare qualsiasi tipo di dati. Forse int , float , double . Non ha un tipo di ritorno che inizialmente è un puntatore creato con il tipo di puntatore (con valore esadecimale) e possiamo assegnare questo puntatore a qualsiasi tipo di dati.

Mentre il puntatore nullo è il puntatore con il valore NULL come indirizzo, al puntatore viene assegnato il valore NULL in modo che non possa essere utilizzato per accedere ad altri dati che il suo indirizzo potrebbe contenere durante la creazione. Penso che sia una buona tecnica di programmazione assegnare un puntatore NULL se non lo si usa al momento.