Câu hỏi này nghe có vẻ ngu ngốc, nhưng tại sao 0đánh giá falsevà bất kỳ giá trị [số nguyên] nào khác truelà 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á truevà 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 strcmplà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 strcmptrả về 0đánh giá falsekhi 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á truethay 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 -1và 1sẽ 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, 0và 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ó comparechứ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 0khi 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á falsetrong một ifđiều kiện, trong khi tất cả các notrườ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á truevà phần còn lại falsesẽ 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à 0là falsevà 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 đó truemột lệnh trả về 0 và điều này cho biết ifđể chạy ....
boolloạ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.