Prima alcuni sfondi ...
The macros are NULL
which expands to an implementation-defined null pointer constant; C11 §7.19 3
NULL
è tipicamente una costante intera 0 o (void*)0
o simile. potrebbe avere un'implementazione o un tipo differente - Potrebbe essere ((int*) 0xDEADBEEF)
così strano come potrebbe essere.
NULL
potrebbe essere il tipo int
. Potrebbe essere di tipo void *
o qualcos'altro. Il tipo di NULL
non è definito.
Quando la costante del puntatore nullo NULL
viene castata su qualsiasi puntatore, è un puntatore nullo . Un intero 0
lanciato su un puntatore è anche un puntatore nullo . Un sistema può avere molti puntatori null (bit-wise) diversi. Sono tutti confronta ugualmente tra loro. Tutti si confrontano in modo ineguale con qualsiasi oggetto / funzione valido. Ricorda che questo confronto è fatto come puntatori, non come numeri interi.
An integer constant expression with the value 0, or such an expression cast to type void *
, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. C11 §6.3.2.3 3
int x;
if (&x == NULL) ... // this is false
Quindi, dopo tutto quel capitolo e verso, come distinguere NULL
da 0
?
Se la macro NULL
è definita come int
0
- è game over - non c'è differenza tra 0
e NULL
.
Se NULL
non è un int
, il codice può utilizzare _Generic()
per differenziare NULL
e 0
. Ciò non aiuta OP "Qualsiasi modifica apportata può essere effettuata solo all'interno della funzione stessa." requisito in quanto tale funzione accetta un int
augment.
Se NULL
è un int
con un modello di bit diverso da 0
, allora un semplice memcmp()
può differenziare.
Sospetto che l'intera ragione di questo esercizio sia capire che non esiste un metodo portatile per distinguere NULL
da 0
.