Uwaga: Ta odpowiedź dotyczy języka C, a nie C ++.
Wskaźniki zerowe
Stała literałowa liczby całkowitej 0ma 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 0to następnie określane jako stała zerowego wskaźnika. Standard C definiuje, że 0rzut na ten typ void *jest zarówno wskaźnikiem zerowym, jak i stałą wskaźnika zerowego.
Dodatkowo, aby poprawić czytelność, makro NULLznajduje się w pliku nagłówkowym stddef.h. W zależności od kompilatora może być możliwe #undef NULLi przedefiniowanie go do czegoś zwariowanego.
Dlatego oto kilka prawidłowych sposobów sprawdzania pustego wskaźnika:
if (pointer == NULL)
NULLjest 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 ifstwierdzenie 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 0stał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.