Uwaga: Ta odpowiedź dotyczy języka C, a nie C ++.
Wskaźniki zerowe
Stała literałowa liczby całkowitej 0
ma różne znaczenia w zależności od kontekstu, w którym jest używana. We wszystkich przypadkach jest to wciąż liczba całkowita z wartością0
, jest ona opisana na różne sposoby.
Jeśli wskaźnik jest porównywany ze stałym literałem 0
, jest to sprawdzenie, czy wskaźnik jest wskaźnikiem zerowym. Jest 0
to następnie określane jako stała zerowego wskaźnika. Standard C definiuje, że 0
rzut na ten typ void *
jest zarówno wskaźnikiem zerowym, jak i stałą wskaźnika zerowego.
Dodatkowo, aby poprawić czytelność, makro NULL
znajduje się w pliku nagłówkowym stddef.h
. W zależności od kompilatora może być możliwe #undef NULL
i przedefiniowanie go do czegoś zwariowanego.
Dlatego oto kilka prawidłowych sposobów sprawdzania pustego wskaźnika:
if (pointer == NULL)
NULL
jest zdefiniowany do porównania równego zerowemu wskaźnikowi. Jest to implementacja zdefiniowana jako rzeczywista definicja NULL
, pod warunkiem, że jest to poprawna stała wskaźnika zerowego.
if (pointer == 0)
0
jest kolejną reprezentacją stałej wskaźnika zerowego.
if (!pointer)
To if
stwierdzenie domyślnie sprawdza, że „nie jest 0”, więc odwracamy to, aby znaczyło „wynosi 0”.
Poniżej przedstawiono NIEPRAWIDŁOWE sposoby sprawdzania pustego wskaźnika:
int mynull = 0;
<some code>
if (pointer == mynull)
Dla kompilatora nie jest to sprawdzenie wskaźnika zerowego, ale sprawdzenie równości dwóch zmiennych. Może to działać, jeśli mynull nigdy się nie zmienia w kodzie, a stała optymalizacji kompilatora składa wartość 0 w instrukcji if, ale nie jest to gwarantowane, a kompilator musi wygenerować co najmniej jeden komunikat diagnostyczny (ostrzeżenie lub błąd) zgodnie ze standardem C.
Zauważ, że czym jest wskaźnik zerowy w języku C. Nie ma to znaczenia dla podstawowej architektury. Jeśli architektura bazowa ma zerową wartość wskaźnika zdefiniowaną jako adres 0xDEADBEEF, to kompilator musi rozwiązać ten problem.
Jako takie, nawet w tej zabawnej architekturze, następujące sposoby są nadal poprawnymi sposobami sprawdzania pustego wskaźnika:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Poniżej przedstawiono NIEPRAWIDŁOWE sposoby sprawdzania pustego wskaźnika:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
ponieważ są one postrzegane przez kompilator jako zwykłe porównania.
Brak znaków
'\0'
jest zdefiniowany jako znak zerowy - jest to znak ze wszystkimi bitami ustawionymi na zero. To nie ma nic wspólnego ze wskaźnikami. Jednak możesz zobaczyć coś podobnego do tego kodu:
if (!*string_pointer)
sprawdza, czy wskaźnik łańcucha wskazuje na znak zerowy
if (*string_pointer)
sprawdza, czy wskaźnik łańcucha wskazuje na znak inny niż null
Nie myl ich ze wskaźnikami zerowymi. Tylko dlatego, że reprezentacja bitów jest taka sama, a to pozwala na pewne wygodne przypadki krzyżowania, nie są to tak naprawdę same.
Dodatkowo '\0'
jest (podobnie jak wszystkie literały znakowe) stałą całkowitą, w tym przypadku o wartości zero. Więc '\0'
jest całkowicie równoważna ozdób 0
stałej liczby całkowitej - jedyną różnicą jest intencją , że przenosi się do ludzkiego czytelnika ( „Używam tego jako znak NULL.”).
Bibliografia
Więcej informacji znajduje się w pytaniu 5.3 w comp.lang.c FAQ . Zobacz ten pdf dla standardu C. Sprawdź sekcje 6.3.2.3 Wskaźniki, akapit 3.