Ngôn ngữ C thực hiện việc "chuyển đổi số học thông thường" đối với nhiều nhà khai thác - các chuyển đổi được nêu trong 6.3.1.8 của tiêu chuẩn C99. Đối với các toán hạng tích phân, các chương trình khuyến mãi đầu tiên được thực hiện và đây là những gì gây ra sự cố của bạn. Các chương trình khuyến mãi được nêu trong 6.3.1.1 (Toán hạng số học/Boolean, ký tự và số nguyên), trong số đó có một số thứ khác:
Nếu int có thể đại diện cho tất cả các giá trị của kiểu gốc, giá trị được chuyển thành giá trị int; nếu không, nó sẽ được chuyển thành int không dấu. Đây được gọi là chương trình khuyến mãi số nguyên. Tất cả các loại khác không thay đổi bởi các chương trình khuyến mãi số nguyên.
Các chương trình khuyến mãi chỉ được áp dụng cho các đối tượng hoặc biểu thức với một kiểu số nguyên với một cấp bậc thấp hơn int
và unsigned int
(hoặc bitfields).
Vì vậy, trong exression của bạn:
t1 < t2-1
mặc dù các biến là unsigned short
họ đang thăng int, vì trên nền tảng của bạn int
thể đại diện cho tất cả các giá trị của unsigned short
. Vì vậy, biểu thức được đánh giá bằng cách sử dụng các loại int
và không có sự cố nào xảy ra - phần t2-1
của biểu thức kết thúc bằng âm 1.
Trong biểu thức:
s1 < s2-1
các unsigned long
loại không được thăng chức, bởi vì họ có một chữ 'rank' cao hơn int
/unsigned int
, vì vậy biểu thức được đánh giá bằng số học unsigned (với underflow từ phép trừ) và biểu thức phụ s2-1
đánh giá đến một số rất lớn, không phải là số âm 1.
Như đã nêu trong một nhận xét, nếu nền tảng đã thực hiện là kiểu 16 bit (được phép - MS-DOS cho ví dụ), người chuyên nghiệp chuyển động của unsigned short
sẽ là unsigned int
thay vì int
, vì int
sẽ không thể đại diện cho tất cả các giá trị của unsigned short
(unsigned short
phải ít nhất 16 bit). Trong trường hợp đó, cả hai câu lệnh if
sẽ được đánh giá là đúng.
Nguồn
2009-09-13 09:50:22
~ nairboon: Tôi hy vọng bạn không ngại chỉnh sửa. Mã tôi thay thế của bạn với chức năng giống nhau, nhưng có thể được sao chép/dán vào một trình soạn thảo và biên soạn mà không thay đổi. –
Lưu ý rằng kết quả này không được đảm bảo là kết quả. Trên máy mà int lưu trữ cùng một phạm vi giá trị như ngắn (16 bit máy sẽ, tôi nghĩ), bạn sẽ thấy đầu ra cho cả hai ifs, bởi vì quảng cáo sẽ chuyển thành int không dấu sau đó, thay vì int. –