( Przeczytaj ten akapit przed przeczytaniem postu.Wszystkich zainteresowanych przeczytaniem tego posta proszę o uważne przeczytanie i oczywiście nie neguj go, dopóki nie zrozumiesz go całkowicie, dzięki. )
Jest to teraz wiki społeczności, jako taka, jeśli ktoś nie zgadza się z którymkolwiek z pojęć, należy go zmodyfikować, podając jasne i szczegółowe wyjaśnienie, co jest nie tak i dlaczego, a jeśli to możliwe, zacytować źródła lub przedstawić dowody, które można odtworzyć.
Odpowiedź
Oto kilka innych powodów, które mogą być podstawowymi czynnikami dla NULL == 0
- Fakt, że zero jest fałszywe, więc można to zrobić bezpośrednio
if(!my_ptr)
zamiast if(my_ptr==NULL)
.
- Fakt, że niewtajemniczone globalne liczby całkowite są domyślnie inicjowane ze wszystkimi zerami i jako taki wskaźnik wszystkich zer byłby uważany za niezainicjowany.
Tutaj chciałbym powiedzieć słowo na temat innych odpowiedzi
Nie z powodu cukru syntaktycznego
Mówienie, że NULL jest równe zero z powodu cukru składniowego, nie ma zbytniego sensu, jeśli tak, dlaczego nie użyć indeksu 0 tablicy do przechowywania jej długości?
W rzeczywistości C jest językiem, który najbardziej przypomina wewnętrzną implementację, czy ma sens powiedzieć, że C wybrał zero tylko z powodu cukru syntaktycznego? Woleliby raczej podać słowo kluczowe null (jak wiele innych języków) niż mapować zero na NULL!
Jako taki, chociaż na dzień dzisiejszy może to być po prostu cukier syntaktyczny, jasne jest, że pierwotnym zamiarem twórców języka C nie był cukier syntaktyczny, co pokażę dalej.
1) Specyfikacja
Chociaż prawdą jest, że specyfikacja C mówi o stałej 0 jako zerowym wskaźniku (sekcja 6.3.2.3), a także definiuje NULL jako definicję implementacji (sekcja 7.19 w specyfikacji C11 i 7.17 w specyfikacji C99), Faktem jest, że w książce „The C Programming Language” napisanej przez wynalazców C w sekcji 5.4 znajduje się, co następuje:
C gwarantuje, że zero nigdy nie jest prawidłowym adresem dla danych, więc wartość zwracana zero może zostać użyta do zasygnalizowania nieprawidłowego zdarzenia, w tym przypadku bez spacji.
Wskaźnik i liczby całkowite nie są zamienne, zero jest jedynym wyjątkiem: stałe zero może być przypisane do wskaźnika, a wskaźnik można porównać ze stałym zerem. Symboliczna stała NULL jest często używana zamiast zera, jako mnemonik wskazujący wyraźniej, że jest to specjalna wartość wskaźnika. NULL jest zdefiniowane w. Odtąd będziemy używać NULL.
Jak widać (ze słów „adres zerowy”) co najmniej pierwotnym zamysłem autorów C był adres zero, a nie stałe zero, ponadto z tego fragmentu wynika, że powód, dla którego specyfikacja przemawia z stałe zero prawdopodobnie nie wyklucza wyrażenia, którego wynikiem jest zero, ale zamiast tego dołącza stałą zero będącą liczbą całkowitą, która będzie jedyną stałą całkowitą dozwoloną do użycia w kontekście wskaźnika bez rzutowania.
2) Podsumowanie
Chociaż specyfikacja nie mówi wprost, że adres zerowy może być traktowany inaczej niż stała zerowa, nie mówi, że nie, a fakt, że mając do czynienia ze stałą wskaźnika zerowego , nie twierdzi, że jest to implementacja zdefiniowana jako robi przez stałą zdefiniowaną przez NULL , zamiast twierdzić, że jest równe zero, pokazuje, że może istnieć różnica między stałą zerową a adresem zerowym.
(Jeśli jednak tak jest, zastanawiam się tylko, dlaczego NULL jest zdefiniowana w implementacji, skoro w takim przypadku NULL może być również stałym zerem, ponieważ kompilator i tak musi przekonwertować wszystkie stałe zerowe na rzeczywistą implementację zdefiniowaną NULL?)
Jednak nie widzę tego w prawdziwym działaniu, a na ogólnych platformach adres zero i stałe zero są traktowane tak samo i generują ten sam komunikat o błędzie.
Ponadto faktem jest, że dzisiejsze systemy operacyjne faktycznie rezerwują całą pierwszą stronę (zakres od 0x0000 do 0xFFFF), aby uniemożliwić dostęp do adresu zerowego z powodu wskaźnika C NULL (patrz http://en.wikipedia.org/wiki/ Zero_page , a także „Windows Via C / C ++ autorstwa Jeffrey'a Richtera i Christophe'a Nasarre'a (opublikowane przez Microsoft Press)”).
Dlatego prosiłbym każdego, kto twierdzi, że rzeczywiście widział to w akcji, o określenie platformy i kompilatora oraz dokładnego kodu, który faktycznie zrobił (chociaż z powodu niejasnej definicji w specyfikacji [jak pokazałem] każdy kompilator a platforma może robić, co chce).
Wygląda jednak na to, że autorzy C nie mieli tego na myśli i mówili o „adresie zerowym”, a „C gwarantuje, że nigdy nie jest to prawidłowy adres”, a także „NULL to tylko mnemonic ”, wyraźnie pokazując, że jego pierwotna intencja nie dotyczyła„ cukru syntaktycznego ”.
Nie z powodu systemu operacyjnego
Twierdząc również, że system operacyjny odmawia dostępu do adresu zerowego z kilku powodów:
1) Kiedy napisano C, nie było takiego ograniczenia, co można zobaczyć na tej stronie http://en.wikipedia.org/wiki/Zero_page .
2) Faktem jest, że kompilatory C miały dostęp do adresu pamięci zero.
Wydaje się, że jest to fakt z następującego artykułu BellLabs ( http://www.cs.bell-labs.com/who/dmr/primevalC.html )
Oba kompilatory różnią się szczegółami, jak sobie z tym radzą. We wcześniejszym, początek znajduje się przez nazwanie funkcji; później, początek jest po prostu równy 0. Wskazuje to, że pierwszy kompilator został napisany, zanim mieliśmy maszynę z mapowaniem pamięci, więc początek programu nie znajdował się w lokalizacji 0, podczas gdy w czasie drugiego, mieliśmy PDP-11, który zapewniał mapowanie.
(W rzeczywistości na dzień dzisiejszy (jak cytowałem powyżej odniesienia z Wikipedii i microsoft press), powodem ograniczenia dostępu do adresu zerowego są wskaźniki C's NULL! Więc na końcu okazuje się, że jest odwrotnie!)
3) Pamiętaj, że C jest również używany do pisania systemów operacyjnych, a nawet kompilatorów C!
W rzeczywistości C został opracowany w celu napisania z nim systemu operacyjnego UNIX i jako taki nie wydaje się być powodem, dla którego mieliby ograniczać się do adresu zero.
(Sprzęt) Wyjaśnienie, w jaki sposób komputery (fizycznie) mogą uzyskać dostęp do adresu zerowego
Jest jeszcze jedna kwestia, którą chcę tutaj wyjaśnić, jak w ogóle można odwołać się do adresu zero?
Pomyśl o tym przez chwilę, adresy są pobierane przez procesor, a następnie wysyłane jako napięcia na magistrali pamięci, która jest następnie używana przez system pamięci, aby dostać się do właściwego adresu, a jednak adres zerowy będzie oznaczał brak napięcia , więc w jaki sposób fizyczny sprzęt systemu pamięci uzyskuje dostęp do adresu zero?
Wydaje się, że odpowiedź brzmi, że adres zerowy jest adresem domyślnym, a innymi słowy adres zero jest zawsze dostępny dla systemu pamięci, gdy magistrala pamięci jest całkowicie wyłączona, i jako takie każde żądanie odczytu lub zapisu bez określenia rzeczywistego adresu (który tak jest w przypadku adresu zero) automatycznie uzyskuje dostęp do adresu zero.
if (p != 0)
naif (p)
który jest powszechnym idiomem w C i C ++, chociaż będziesz musiał pozbyć się tego nawyku, jeśli zdecydujesz się na Javę.