Durante il test per NULL
, vedo un sacco di codice che utilizza !var
. C'è un motivo per utilizzare questo tipo di test rispetto al più esplicito var == NULL
. Allo stesso modo, if (var)
dovrebbe essere un test corretto per un articolo non null?Dovrebbe essere usato `! Var` o` var == NULL`?
risposta
La differenza tra:
!var
e
var == NULL
è nel secondo caso il compilatore devono emettere una diagnosi se var
non è di tipo puntatore e NULL
è definito con un cast (come (void *) 0
).
Inoltre, come indicato da @ bitmask nei commenti, per utilizzare la macro NULL
, è necessario includere un'intestazione standard che definisca la macro NULL
. In C la macro NULL
è definita in diverse intestazioni per comodità (come stddef.h
, stdio.h
, stdlib.h
, string.h
, ecc.).
Altrimenti le due espressioni sono equivalenti ed è solo una questione di gusti. Usa quello che ti senti più a tuo agio.
E per la seconda domanda if (var)
corrisponde a if (var != NULL)
con la differenza sopra indicata.
Si noti che è necessario definire almeno una delle diverse intestazioni per 'NULL'. – bitmask
@ bitmask buon punto, lo aggiungo alla mia risposta. – ouah
http://c-faq.com/null/ptrtest.html dice 'if (var) è equivalente a if (var! = 0)' e molto più roba sui puntatori nulli. Inoltre, questa domanda non è già stata posta? vedi http://stackoverflow.com/a/3825704/1273830 è diverso somehome? – Prasanth
I ISO/IEC 9899 norma stabilisce che:
come del linguaggio: una costante espressione intera con il valore
0
, o una tale espressione fuso al tipovoid *
, è chiamato un puntatore nullo costante. Se una costante del puntatore nullo viene convertita in un tipo di puntatore, il puntatore risultante, chiamato puntatore nullo, viene garantito per confrontare non uguale a un puntatore a qualsiasi oggetto o funzione.come da librerie:
NULL
è una macro che si espande alla costante del puntatore nullo definita dall'implementazione.
Ciò significa che le espressioni fornite sono ugualmente "corrette". La ragione per preferire una forma piuttosto che un'altra è in gran parte una questione di gusti.
Cioè, se si dispone di un compilatore minimo senza avvisi oltre a quanto richiesto dallo standard. Se ne hai uno moderno, diciamo uno realizzato dopo il 1991, riceverai gli avvisi del compilatore se provassi a confrontare una variabile non puntatore con NULL. – Lundin
Ecco perché abbiamo: 'gcc -w' – geocar
Dalla norma C:
tipi aritmetici e tipi di puntatore sono chiamati collettivamente tipi scalari.
L'operando dell'operatore unario + o - deve essere di tipo aritmetico; dell'operatore ~, tipo intero; del! operatore, tipo scalare.
Il risultato dell'operatore di negazione logica! è 0 se il valore del suo operando confronta non uguale a 0, 1 se il valore del suo operando è uguale a 0. Il risultato ha tipo int. L'espressione! E è equivalente a (0 == E).
Quindi, questo dovrebbe rispondere alla tua domanda.
In realtà no, a meno che tu non sappia come viene definito' NULL'. –
La versione == NULL ha un vantaggio importante: consente al compilatore e agli analizzatori statici di trovare un particolare bug comune.
Supponiamo che "var" non sia un puntatore, ma una variabile allocata. if(!var)
sarebbe quindi un bug che passava inosservato.
NULL è spesso dichiarato come #define NULL ((void*)0)
. Questa dichiarazione non è obbligatoria per lo standard, ma uno dei più comuni. Un compilatore di tipo semidecente controllo sarebbe quindi in grado di produrre un avvertimento per codice come questo:
int var = ...;
if(var == NULL) // compiler warning, var is not a pointer
Oltre al vantaggio di cui sopra, è anche stilisticamente corretto non utilizzare l'operatore !
, dato che è un operatore logico, pensato per essere usato su variabili booleane, non puntatori. Funziona solo perché C non ha una digitazione forte.
Suggerirei di seguire MISRA-C in questa materia, che impone di rendere espliciti i controlli su NULL o zero. if(x != NULL)
anziché if(x)
. Il fondamento logico di queste regole è un codice più leggibile. Si traduce comunque nello stesso codice macchina, quindi non c'è nulla di male nel rendere il codice più facile da leggere.
- 1. lascia var o var per lasciare
- 2. Utilizzando var o non utilizzo di var
- 3. isset ($ var) vs. @ $ var
- 4. jQuery var e $ (var) css
- 5. Qual è la differenza tra "var = $ {var: -word}" e "var = $ {var: = word}"?
- 6. dovrebbe mai essere usato encodeURI?
- 7. Variabili qmake, differenza di $$ VAR e $$ {VAR}
- 8. Come inizializzare var?
- 9. La directory di un documento dell'app iPhone è/var/mobile/Documents o/var/mobile/Library/AppName?
- 10. var in C# - Perché non può essere usato come variabile membro?
- 11. bash conditionals: come "e" espressioni? (se [! -z $ VAR && -e $ VAR])
- 12. var vs dichiarazione esplicita
- 13. Dovrebbe essere sempre usato std :: endl?
- 14. NSInteger dovrebbe essere usato davvero ovunque?
- 15. JavaScript se var esiste
- 16. Scopo di /var/resource_config.json
- 17. Quando dovrebbe essere usato un memoryview?
- 18. Quando dovrebbe essere usato std :: atomic_compare_exchange_strong?
- 19. differenza tra var parola chiave var e senza
- 20. È meglio scrivere: var arr = []; di var arr = new Array() ;?
- 21. foreach my $ var (@list) - $ var è un riferimento?
- 22. Codice strano in sorgenti jQuery: var! == var? x: y;
- 23. In che modo "+ var === + var" funziona internamente per verificare se var è numerico?
- 24. var undefined = true;
- 25. subprocess.call env var
- 26. Php: qual è la differenza tra $ var e & $ var?
- 27. Differenze tra "static var" e "var" in Swift
- 28. PHP: Perché typecast con !! $ var invece di (boolean) $ var?
- 29. PHP IF per i valori booleani: $ var === vero vs $ var
- 30. C - Differenza tra "char var []" e "char * var"?
Per ragioni formali, preferisco quest'ultimo - rende l'intento più chiaro. Ma entrambi sono accettabili. –
Trovato una domanda molto simile: http://stackoverflow.com/questions/459743/is-null-always-false – Matt
possibile duplicato di [C/C++ Checking per il puntatore NULL] (http://stackoverflow.com/questions/ 3825668/cc-checking-per-null-pointer) –