2010-02-28 12 views
12

Tôi có mảng sau, tôi cần vận hành bằng tay trên bitmap.C++: Cảnh báo biên dịch cho số lớn chưa ký int

const unsigned int BITS[32] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 
           2048, 4096, 8192, 16384, 32768, 65536, 131072, 
           262144, 524288, 1048576, 2097152, 4194304, 
           8388608, 16777216, 33554432, 67108864, 134217728, 
           268435456, 536870912, 1073741824, 2147483648}; 

Thật không may, khi biên soạn tôi nhận được

cảnh báo: hằng số thập phân này là unsigned chỉ trong ISO C90

Làm thế nào tôi có thể loại bỏ điều này?

+0

Xem câu hỏi tương tự này: http://stackoverflow.com/questions/2347936/cant-get-ride-of-this-decimal-constant -is-unsigned-only-in-iso-c90-warning –

+0

Tại sao bạn làm điều này? Nếu bạn nghĩ rằng một bảng tra cứu sẽ nhanh hơn chỉ đơn giản là tính toán các giá trị này khi cần thiết, hãy suy nghĩ lại ... – Nemo

Trả lời

15

Chữ số nguyên trong C theo mặc định là loại "ký tự int" (chỉnh sửa: nhưng xem chú thích để báo trước). Số cuối cùng có quá lớn để có thể biểu diễn dưới dạng một ký 32-bit số nguyên, và do đó bạn cần phải nói với trình biên dịch rằng đó là một số nguyên unsigned bởi suffixing nó với "U", như:

2147483648U 

Lưu ý rằng bạn cũng có thể thêm hậu tố "L" để tạo thành "dài", nhưng trên nhiều hệ thống vẫn còn 32 bit và do đó không liên quan.

Ngoài ra, có một cách dễ bị lỗi (và dễ dàng hơn để đọc) ít nhiều để viết mã này, với các nhà điều hành chút ca:

const unsigned int BITS[32] = {1U, 1U<<1, 1U<<2, 1U<<3, 1U<<4, 
           /* and so on */ 
           1U<<31}; 

Hoặc, viết trong hệ thập lục phân, nếu bạn don Không thích thay đổi chút ít vì một lý do nào đó:

const unsigned int BITS[32] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 
           /* and so on */ 
           0x80000000U}; 
+0

Tại sao trình biên dịch xử lý nó sau đó như là một int, thay vì sau đó tự động biến nó thành uint? Đặc biệt, nó chính xác biết trong loại nó sẽ được lưu trữ. – gruszczy

+0

Trong nhiều trường hợp, bạn không thể biết loại hằng số là gì (ví dụ, như một đối số hàm trong một hàm varargs) vì vậy nó phải được xác định rõ ràng. Rất khó để có loại được ngụ ý một số lần và cần phải được quy định rõ ràng ở những người khác, và cũng khó hiểu để có cùng một loại liên tục trên các hệ thống có kích thước int khác nhau. Ngoài ra, bởi vì C không bao giờ loại suy luận của loại đó, thêm nó cho một trường hợp này sẽ làm phức tạp các trình phân tích cú pháp khá nhiều mà không có lợi ích đáng kể. –

+3

@gruszczy: Trong C89/90 hằng số thập phân không được trộn lẫn phải được hiểu là 'int',' long' hoặc 'unsigned long' (tùy theo điều kiện nào phù hợp trước). Trong C99, nó phải được hiểu là 'int',' long' hoặc 'long long' (tùy theo cái nào phù hợp trước). Điều này trình biên dịch đang cố gắng nói gì bởi cảnh báo này. Rõ ràng, trên nền tảng này 'long' có cùng kích thước với' int'. Trình biên dịch về cơ bản là nói: "có thể bạn đang cố gắng tạo ra một' ký dài' connstant hoặc thậm chí có thể là một 'long long' liên tục, nhưng theo các quy tắc C89/90 tôi phải làm cho nó 'unsigned long' – AnT

6

liên tục của bạn phải được quy định như unsigned quá, sử dụng

2147483648UL 

(UL = Unsigned Long), hoặc đơn giản là

2147483648U 

cho một int unsigned.

Vì mã của bạn là ngay bây giờ, một hằng số, theo mặc định là đồng bằng int và do đó được ký, được gán cho một unsigned int, tạo cảnh báo của bạn.

+0

Điều đó làm việc, cảm ơn rất nhiều :-) – gruszczy

+3

Nói một cách đơn giản, lỗi không phải là do thực tế (đồng bằng int) hằng số được gán cho một int không dấu; nhiệm vụ không liên quan. Lỗi này là do giá trị của "2147483648" quá lớn để là một int đã ký, và do đó, có một tràn trong việc tạo ra hằng số int đã ký ở vị trí đầu tiên. –

+2

Trên thực tế, lý do thực sự cho cảnh báo là trình biên dịch phải chọn 'unsigned long' cho loại liên tục. (Lưu ý, một lần nữa, hằng số này không phải là 'unsigned int', nó là' unsigned long'.) Và nó phải chọn nó trong C89/90 đặc biệt, thay vì chọn một loại ký lớn hơn (có thể hỗ trợ) hoặc theo C99 quy tắc và chọn 'long long'. Đây là những gì cảnh báo là về và tại sao nó đề cập đến 'ISO C90'. Trong C99, ví dụ, một hằng số thập phân không được trộn lẫn sẽ không bao giờ được đưa ra một kiểu unsigned. – AnT

1

Không cần thiết để xác định loại dữ liệu là loại chưa ký;

int variable_name=2147483648U; 

khác chỉ chuyển đổi giá trị thập phân để hex ...