To pytanie może wydawać się głupie, ale dlaczego 0ewaluuje falsei jakąkolwiek inną wartość [całkowitą] trueto 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 0ewaluuje truei 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 strcmpjako 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ż strcmpzwroty, 0które oceniają, falsekiedy ł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 truezamiast 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 -1i 1został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, 0a 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ż comparefunkcja, 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 0zostali 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ą 0po 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 yesoceniają falsepod ifwarunkiem, podczas gdy wszystkie noprzypadki 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 0oceny truei reszty do falsebyłoby znacznie bardziej sensowne.
Wniosek
Mój wniosek jest zasadniczo moim pierwotnym pytaniem: dlaczego zaprojektowaliśmy języki, gdzie 0są falsei 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 truejest poleceniem, które zwraca zero, a to każe ifuruchomić ....
booltypu, 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.