Czy wskaźnik wskazujący na 0x0000 jest taki sam jak wskaźnik ustawiony na NULL? Jeśli wartość NULL jest zdefiniowana w języku C, to w którą lokalizację fizycznie tłumaczy? Czy to to samo co 0x0000. Gdzie mogę znaleźć więcej szczegółów na temat tych pojęć?
12
Odpowiedzi:
Punktem, że większość odpowiedzi tutaj nie odnosi się, przynajmniej nie wprost, jest to, że wskaźnik zerowy jest wartością, która istnieje podczas wykonywania, a stała zerowego wskaźnika jest konstrukcją składniową, która istnieje w kodzie źródłowym C.
Stała wskaźnika zerowego , jak słusznie stwierdza odpowiedź Karlsona, jest albo stałym wyrażeniem całkowitym o wartości 0 (
0
najczęstszym przykładem jest prosty ), albo takim wyrażeniem przypisanym dovoid*
(takim jak(void*)0
).NULL
to makro zdefiniowane w<stddef.h>
kilku innych standardowych nagłówkach, które rozwija się do zdefiniowanej implementacji stałej wskaźnika zerowego . Rozbudowa jest zazwyczaj0
lub((void*)0)
(potrzebne jest zewnętrzne nawiasach spełniać inne zasady językowe).Tak dosłowna
0
, kiedy używany w kontekście, który wymaga wyrażenia typu wskaźnik, zawsze wynikiem jestnull pointer
, czyli unikalną wartość wskaźnika, który wskazuje na żaden obiekt. Że nie nie nic o reprezentacji implikuje wskaźnik NULL . Wskaźniki zerowe są bardzo często reprezentowane jako zero-bitowe, ale mogą być reprezentowane jako dowolne. Ale nawet jeśli wskaźnik zerowy jest reprezentowany jako0xDEADBEEF
,0
lub(void*)0
nadal jest stałą wskaźnika zerowego .To odpowiedź na pytanie o stackoverflow Obejmuje to dobrze.
To implikuje, między innymi, że
memset()
lubcalloc()
, który może ustawić region pamięci na zero-bitów, niekoniecznie ustawi wskaźniki w tym obszarze na wskaźniki zerowe. Prawdopodobnie zrobią to na większości implementacji, ale język tego nie gwarantuje.Nie wiem, dlaczego ta kwestia nie jest uważane za duplikat tej jednej , albo jak to miejscowe tutaj.
źródło
NULL
lub dowolna stała wskaźnika zerowego do obiektu wskaźnika ustawia wartość tego obiektu na wskaźnik zerowy . Na poziomie maszyny może to wskazywać na prawidłową porcję pamięci. Dereferencje wskaźnika zerowego mają niezdefiniowane zachowanie; dostęp do części pamięci pod adresem0x0000000
jest prawidłowym zachowaniem, podobnie jak dosłownie wszystko inne. Ten adres różni się od dowolnego innego adresu przez (a) porównanie równeNULL
i (b) porównanie nierówne z dowolnym wskaźnikiem do obiektu C. Wskaźnik zerowy to dowolna wartość wskaźnika używana do wskazania, że nie wskazuje na nic.Każda platforma może zdefiniować NULL według własnego uznania.
Zgodnie ze standardem C, jeśli przypiszesz zero do wskaźnika, zostanie on przekonwertowany na wartość NULL (dla tej platformy). Jeśli jednak weźmiesz wskaźnik NULL i rzucisz go na int, nie ma gwarancji, że otrzymasz zero na każdej platformie. Faktem jest jednak, że na większości platform będzie to zero.
Informacja o takie rzeczy można znaleźć w katalogu C Language Specification . Jednym ze źródeł, za których wiarygodność nie mogę ręczyć, jest: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
źródło
NULL pointer constant
. O ile mi wiadomo, nie ma kompilatorów, które to robią.NULL
makra, które ma rozwijać się0
w C ++ i albo0
czy(void *)0
w C, ponieważ jest to prawdziwa „stała zerowego wskaźnika”.Jest zdefiniowany w języku C, ponieważ nie ma jednego niezmiennego adresu maszyny, który byłby mu równy. Gdyby tak było, nie potrzebowalibyśmy od niego abstrakcji! Mimo że na większości platform NULL może ostatecznie zostać zaimplementowany jako 0 jakiegoś typu, to po prostu błędem jest założyć, że jest to uniwersalne, jeśli zależy ci na przenośności.
źródło
Zgodnie z sekcją dokumentu standardowego C
6.3.2.3
:Do tej pory nie widziałem kompilatora, który to oderwał.
źródło