Bạn đang trộn lẫn rất nhiều thứ khác nhau: câu lệnh điều khiển, toán tử và kiểu boolean. Mỗi người có quy tắc riêng của họ.
Câu lệnh điều khiển hoạt động giống như câu lệnh ví dụ if
, C11 6.4.8.1:
Trong cả hai dạng, câu lệnh con đầu tiên được thực thi nếu biểu thức so sánh không bằng 0.
while
, for
vv có cùng một quy tắc. Điều này không liên quan gì đến "true" hoặc "false".
Đối với các toán tử được cho là mang lại kết quả boolean, chúng thực sự đang mang lại int
giá trị 1 hoặc 0. Ví dụ: các toán tử bình đẳng, C11 6.5.9:
Mỗi toán tử cho kết quả 1 nếu quan hệ đã chỉ định là đúng và 0 nếu sai
Tất cả những điều trên là do C không có kiểu boolean cho đến năm 1999, và ngay cả khi có kiểu boolean, các quy tắc trên vẫn không thay đổi. Vì vậy, không giống như hầu hết các ngôn ngữ lập trình khác, nơi các câu lệnh và toán tử mang lại kiểu boolean (như C ++ và Java), chúng chỉ mang lại một int
, với giá trị bằng không hoặc không bằng không. Ví dụ, sizeof(1==1)
sẽ cho 4 trong C nhưng 1 trong C ++.
Kiểu boolean thực tế trong C được đặt tên _Bool
và yêu cầu trình biên dịch hiện đại. Tiêu đề stdbool.h
xác định các macro bool
, true
và false
mở rộng tới _Bool
, 1
và 0
tương ứng (để tương thích với C ++).
Tuy nhiên, nó được coi là phương pháp lập trình tốt để xử lý các câu lệnh điều khiển và toán tử như thể chúng thực sự yêu cầu / mang lại một kiểu boolean. Một số tiêu chuẩn mã hóa như MISRA-C khuyến nghị thực hành như vậy. Đó là:
if(ptr == NULL)
thay vì if(ptr)
.
if((data & mask) != 0)
thay vì if(data & mask)
.
Mục đích của phong cách như vậy là để tăng độ an toàn của kiểu với sự hỗ trợ của các công cụ phân tích tĩnh, do đó làm giảm lỗi. Có thể cho rằng, kiểu này chỉ có ý nghĩa nếu bạn sử dụng máy phân tích tĩnh. Mặc dù trong một số trường hợp, nó dẫn đến mã tự ghi lại dễ đọc hơn, chẳng hạn
if(c == '\0')
Tốt, mục đích rõ ràng, mã tự ghi lại.
đấu với
if(c)
Xấu. Có thể có nghĩa là bất cứ điều gì, và chúng tôi phải đi tìm loại c
để hiểu mã. Nó là một số nguyên, một con trỏ hay một ký tự?