2017-04-24 14 views
5

Tôi có nghi ngờ từ hai đoạn mã dưới đây.Lỗi dữ liệu khi so sánh các giá trị

Tôi đã chạy mã này trên máy 64 bit (x86_64-linux-gnu). Tôi có thể thấy giá trị Val tràn khi loại dữ liệu là unsigned integer.

#include<stdio.h> 
main() 
{ 
    unsigned int Val = 0xFFFFFFFF-15, Val2 = 0xFFFFFFFF; 
    if (Val+16 < Val2) 
    { 
     printf("Val is less than Val2\n"); 
    } 
} 

Nếu kiểu dữ liệu là unsigned char thì không tràn.

#include<stdio.h> 
main() 
{ 
    unsigned char Val = 0xFF-15, Val2 = 0xFF; 
    if (Val+16 < Val2) 
    { 
     printf("Val is less than Val2\n"); 
    } 
} 

Tôi có hai câu hỏi:

  1. Có giá trị Val được thăng tiến đến kiểu dữ liệu cao khi kiểu dữ liệu là unsigned char?
  2. Nếu có, tại sao quảng cáo không được thăng hạng từ 32 bit đến 64 bit unsigned long?
+8

Đây không phải là của thập niên 90 - kiểu trả về trên 'main' là bắt buộc hiện nay. – InternetAussie

+0

Khi thực hiện phép tính số học, mọi thứ được quảng bá thành 'int' nếu có thể phù hợp, hoặc thành' unsigned int' nếu không thể. Kích thước của các loại này là cụ thể cho trình biên dịch của bạn và bạn có thể dễ dàng tìm thấy nó. –

Trả lời

6

Tiêu chuẩn C11 cho biết như sau (C11 6.3.11p2.2):

Nếu một int thể đại diện cho tất cả các giá trị của các loại gốc (như hạn chế bởi chiều rộng, đối với một bit-field), giá trị được chuyển đổi thành int; nếu không, nó được chuyển thành một số unsigned int. Đâ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 theo các chương trình khuyến mãi số nguyên.

Như vậy:

  1. unsigned char sẽ được thúc đẩy - tuy nhiên nó là một chi tiết thực hiện liệu int thể đại diện cho tất cả các giá trị của unsigned char - vì vậy nó có thể được đề bạt lên một unsigned int trên các nền tảng. Bạn không phải là một trong những nền tảng đó, do đó so sánh thứ hai của bạn là (int)Val + 16 < (int)Val2.

  2. là câu cuối cùng của đoạn được trích dẫn cho biết, unsigned int không bao giờ được quảng cáo. Vì số học được thực hiện trên int không dấu trong đoạn đầu tiên, kết quả của 0xFFFFFFFF - 15 + 160U trên máy tính có int không dấu 32 bit.

2

Có, trong trường hợp thứ hai, các số được thăng cấp thành int. Nếu bạn sửa đổi mã của mình như vậy:

#include<stdio.h> 
int main() 
{ 
    unsigned char Val = 0xFF-15, Val2 = 0xFF; 
    if ((unsigned char)(Val+16) < Val2) 
    { 
     printf("Val is less than Val2\n"); 
    } 
} 

Bạn sẽ nhận được hành vi mà bạn mong đợi.

+0

Cảm ơn tất cả các bạn. Nó rất rõ ràng bây giờ. –

Các vấn đề liên quan