Câu hỏi này nghe có vẻ ngu ngốc, nhưng tại sao 0
đánh giá false
và bất kỳ giá trị [số nguyên] nào khác true
là hầu hết các ngôn ngữ lập trình?
So sánh chuỗi
Vì câu hỏi có vẻ hơi đơn giản, tôi sẽ tự giải thích thêm một chút: trước hết, nó có vẻ hiển nhiên đối với bất kỳ lập trình viên nào, nhưng tại sao lại không có ngôn ngữ lập trình - thực sự có thể có, nhưng không phải Tôi đã sử dụng - nơi 0
đánh giá true
và tất cả các giá trị [số nguyên] khác false
? Đó là một nhận xét có vẻ ngẫu nhiên, nhưng tôi có một vài ví dụ mà nó có thể là một ý tưởng tốt. Trước hết, hãy lấy ví dụ về chuỗi so sánh ba chiều, tôi sẽ lấy C strcmp
làm ví dụ: bất kỳ lập trình viên nào thử C làm ngôn ngữ đầu tiên của anh ta có thể bị cám dỗ để viết mã sau đây:
if (strcmp(str1, str2)) { // Do something... }
Vì các strcmp
trả về 0
đánh giá false
khi các chuỗi bằng nhau, những gì lập trình viên ban đầu đã cố gắng làm thất bại thảm hại và anh ta thường không hiểu tại sao lúc đầu. Đã được 0
đánh giá true
thay vào đó, chức năng này có thể đã được sử dụng trong biểu thức đơn giản nhất của nó - hàm trên - khi so sánh về đẳng thức, và kiểm tra thích hợp cho -1
và 1
sẽ chỉ được thực hiện khi cần. Chúng tôi đã có thể coi loại trả lại là bool
(trong suy nghĩ của chúng tôi ý tôi) hầu hết thời gian.
Hơn nữa, chúng ta hãy giới thiệu một loại mới, sign
, mà chỉ mất giá trị -1
, 0
và 1
. Điều đó có thể khá tiện dụng. Hãy tưởng tượng có một toán tử tàu vũ trụ trong C ++ và chúng tôi muốn nó std::string
(tốt, đã có compare
chức năng, nhưng toán tử tàu vũ trụ thú vị hơn). Tuyên bố hiện tại sẽ là một trong những điều sau đây:
sign operator<=>(const std::string& lhs, const std::string& rhs);
Đã 0
được đánh giá true
, toán tử tàu vũ trụ thậm chí sẽ không tồn tại và chúng ta có thể đã tuyên bố operator==
theo cách đó:
sign operator==(const std::string& lhs, const std::string& rhs);
Điều này operator==
sẽ xử lý so sánh ba chiều cùng một lúc và vẫn có thể được sử dụng để thực hiện kiểm tra sau trong khi vẫn có thể kiểm tra chuỗi nào vượt trội hơn so với chuỗi khác khi cần:
if (str1 == str2) { // Do something... }
Xử lý lỗi cũ
Bây giờ chúng ta có ngoại lệ, vì vậy phần này chỉ áp dụng cho các ngôn ngữ cũ, nơi không có thứ đó tồn tại (ví dụ C). Nếu chúng ta xem thư viện chuẩn của C (và cả POSIX nữa), chúng ta có thể thấy chắc chắn rằng các hàm maaaaany trở lại 0
khi thành công và bất kỳ số nguyên nào khác. Tôi đã buồn khi thấy một số người làm điều này:
#define TRUE 0
// ...
if (some_function() == TRUE)
{
// Here, TRUE would mean success...
// Do something
}
Nếu chúng ta nghĩ về cách chúng ta nghĩ trong lập trình, chúng ta thường có mẫu lý luận sau:
Do something
Did it work?
Yes ->
That's ok, one case to handle
No ->
Why? Many cases to handle
Nếu chúng ta nghĩ về nó một lần nữa, sẽ có ý nghĩa khi đặt giá trị trung tính duy nhất 0
, yes
(và đó là cách các chức năng của C hoạt động), trong khi tất cả các giá trị khác có thể ở đó để giải quyết nhiều trường hợp no
. Tuy nhiên, trong tất cả các ngôn ngữ lập trình mà tôi biết (ngoại trừ có thể một số ngôn ngữ thực nghiệm thử nghiệm), sẽ yes
đánh giá false
trong một if
điều kiện, trong khi tất cả các no
trường hợp ước tính true
. Có nhiều tình huống khi "nó hoạt động" đại diện cho một trường hợp trong khi "nó không hoạt động" đại diện cho nhiều nguyên nhân có thể xảy ra. Nếu chúng ta nghĩ về nó theo cách đó, việc 0
đánh giá true
và phần còn lại false
sẽ có ý nghĩa hơn nhiều.
Phần kết luận
Kết luận của tôi về cơ bản là câu hỏi ban đầu của tôi: tại sao chúng tôi thiết kế ngôn ngữ mà 0
là false
và các giá trị khác true
, dùng trong tài khoản vài ví dụ của tôi ở trên và có thể một số chi tiết tôi không nghĩ ra?
Theo dõi: Thật tuyệt khi thấy có nhiều câu trả lời với nhiều ý tưởng và càng nhiều lý do có thể khiến nó trở nên như vậy. Tôi yêu cách bạn đam mê dường như về nó. Tôi ban đầu hỏi câu hỏi này vì chán, nhưng vì bạn có vẻ rất say mê, tôi quyết định đi xa hơn một chút và hỏi về lý do đằng sau sự lựa chọn Boolean cho 0 và 1 trên Math.SE :)
if true ; then ... ; fi
, trong đó true
một lệnh trả về 0 và điều này cho biết if
để chạy ...
.
bool
loại nhưng so sánh / nếu điều kiện vv có thể có bất kỳ giá trị trả về.
strcmp()
không có ví dụ tốt cho đúng hay sai, vì nó trả về 3 giá trị khác nhau. Và bạn sẽ ngạc nhiên khi bạn bắt đầu sử dụng shell, trong đó 0 có nghĩa là đúng và bất cứ điều gì khác có nghĩa là sai.