To pytanie może wydawać się głupie, ale dlaczego 0
ewaluuje false
i jakąkolwiek inną wartość [całkowitą] true
to większość języków programowania?
Porównanie ciągów
Ponieważ pytanie wydaje się nieco zbyt proste, wyjaśnię się trochę bardziej: po pierwsze, może się wydawać oczywiste dla każdego programisty, ale dlaczego nie byłoby języka programowania - może być, ale nie może Użyłem - gdzie 0
ewaluuje true
i wszystkie inne wartości [całkowite] false
? Ta jedna uwaga może wydawać się przypadkowa, ale mam kilka przykładów, w których może to być dobry pomysł. Po pierwsze, weźmy przykład trójstronnego porównania ciągów, wezmę C strcmp
jako przykład: każdy programista próbujący C jako swojego pierwszego języka może ulec pokusie napisania następującego kodu:
if (strcmp(str1, str2)) { // Do something... }
Ponieważ strcmp
zwroty, 0
które oceniają, false
kiedy łańcuchy są równe, to, co początkowy programista próbował zrobić, kończy się niepowodzeniem i na ogół nie rozumie dlaczego na początku. Oceniając, 0
że true
zamiast tego, funkcja ta mogłaby zostać użyta w jej najprostszym wyrażeniu - powyższym - przy porównywaniu pod kątem równości, a odpowiednie kontrole dla -1
i 1
zostałyby wykonane tylko w razie potrzeby. Przez większość czasu uważalibyśmy ten typ zwrotu za bool
(naszym zdaniem ).
Ponadto, niech wprowadzi nowy typ, sign
, że po prostu ma wartości -1
, 0
a 1
. To może być całkiem przydatne. Wyobraź sobie, że w C ++ jest operator statku kosmicznego i my go potrzebujemy std::string
(cóż, jest już compare
funkcja, ale operator statku kosmicznego jest bardziej zabawny). Deklaracja będzie obecnie następująca:
sign operator<=>(const std::string& lhs, const std::string& rhs);
Gdybyśmy 0
zostali oceniani true
, operator statku kosmicznego nawet by nie istniał i moglibyśmy w operator==
ten sposób zadeklarować :
sign operator==(const std::string& lhs, const std::string& rhs);
To operator==
poradziłoby sobie z porównywaniem w trzech kierunkach jednocześnie i nadal mogłoby być użyte do wykonania następującego sprawdzenia, a jednocześnie byłoby w stanie sprawdzić, który ciąg znaków jest lepszy leksykograficznie od drugiego w razie potrzeby:
if (str1 == str2) { // Do something... }
Stara obsługa błędów
Mamy teraz wyjątki, więc ta część dotyczy tylko starych języków, w których nic takiego nie istnieje (na przykład C). Jeśli spojrzymy na standardową bibliotekę C (a także POSIX), możemy zobaczyć na pewno, że funkcje maaaaany powrócą 0
po pomyślnym zakończeniu, a dowolna liczba całkowita w przeciwnym razie. Niestety niektórzy ludzie robią takie rzeczy:
#define TRUE 0
// ...
if (some_function() == TRUE)
{
// Here, TRUE would mean success...
// Do something
}
Jeśli myślimy o tym, jak myślimy w programowaniu, często mamy następujący wzór rozumowania:
Do something
Did it work?
Yes ->
That's ok, one case to handle
No ->
Why? Many cases to handle
Jeśli pomyślimy o tym jeszcze raz, sensowne byłoby umieszczenie jedynej wartości neutralnej 0
, do yes
(i tak działają funkcje C), podczas gdy wszystkie inne wartości mogą tam być, aby rozwiązać wiele przypadków no
. Jednak we wszystkich językach programowania, które znam (oprócz być może niektórych eksperymentalnych języków ezoterycznych), które yes
oceniają false
pod if
warunkiem, podczas gdy wszystkie no
przypadki oceniają true
. Istnieje wiele sytuacji, w których „to działa” reprezentuje jeden przypadek, podczas gdy „to nie działa” reprezentuje wiele prawdopodobnych przyczyn. Jeśli pomyślimy o tym w ten sposób, dokonanie 0
oceny true
i reszty do false
byłoby znacznie bardziej sensowne.
Wniosek
Mój wniosek jest zasadniczo moim pierwotnym pytaniem: dlaczego zaprojektowaliśmy języki, gdzie 0
są false
i inne wartości true
, biorąc pod uwagę moje kilka przykładów powyżej, a może kilka innych, o których nie myślałem?
Dalsze działania: Miło jest widzieć, że istnieje wiele odpowiedzi z wieloma pomysłami i tak wiele możliwych powodów, aby tak było. Uwielbiam, jak bardzo pasjonujesz się tym. Oryginalnie zadałem to pytanie z nudów, ale ponieważ wydajesz się tak namiętny, postanowiłem pójść nieco dalej i zapytać o uzasadnienie logicznego wyboru dla 0 i 1 na Math.SE :)
if true ; then ... ; fi
, gdzie true
jest poleceniem, które zwraca zero, a to każe if
uruchomić ...
.
bool
typu, ale porównań / jeśli warunki itd. Może mieć dowolną wartość.
strcmp()
nie jest dobrym przykładem wartości prawda lub fałsz, ponieważ zwraca 3 różne wartości. Będziesz zaskoczony, gdy zaczniesz używać powłoki, gdzie 0 oznacza prawda, a wszystko inne oznacza fałsz.