Khi nào sử dụng các giá trị chưa được ký trên các giá trị đã ký?


81

Khi nào thì thích hợp để sử dụng biến không dấu thay vì biến có dấu? Điều gì về trong một forvòng lặp?

Tôi nghe rất nhiều ý kiến ​​về điều này và tôi muốn xem liệu có điều gì giống với sự đồng thuận không.

for (unsigned int i = 0; i < someThing.length(); i++) {  
    SomeThing var = someThing.at(i);  
    // You get the idea.  
}

Tôi biết Java không có các giá trị không dấu, và đó hẳn là một quyết định sáng suốt về phía Sun Microsystems .


1
Tôi thấy điều này hữu ích: codemines.blogspot.ca/2007/10/...
mk12

Tôi nghĩ câu hỏi này khá dựa trên quan điểm. Mã được trình bày sẽ chạy tốt trong cả hai trường hợp, vì vậy bạn có thể sử dụng cả hai. Ngoại trừ lý do hiệu suất (không có câu trả lời thực sự liên quan đến hiệu suất cho đến nay) đó chỉ là sở thích cá nhân.
Trilarion

Câu trả lời:


69

Tôi rất vui khi tìm thấy một cuộc trò chuyện tốt về chủ đề này, vì trước đây tôi chưa thực sự nghĩ nhiều về nó.

Tóm lại, ký là một lựa chọn chung tốt - ngay cả khi bạn chắc chắn rằng tất cả các số đều là số dương - nếu bạn định tính toán số học trên biến (như trong trường hợp vòng lặp for điển hình).

Nếu bạn định làm những thứ khôn ngoan như mặt nạ, không dấu bắt đầu có ý nghĩa hơn. Hoặc, nếu bạn đang muốn đạt được phạm vi tích cực hơn đó bằng cách tận dụng bit dấu hiệu.

Cá nhân tôi thích ký vì tôi không tin tưởng bản thân mình sẽ nhất quán và tránh trộn lẫn hai loại (như bài báo đã cảnh báo).


3
Sau đó trong luồng đó, nó được chứng minh unsignedlà vượt trội hơn rất nhiều trong việc phát hiện tràn trong các đầu vào không đáng tin cậy. Thật không may, các "câu trả lời" được đề xuất cho câu đố không phải là tất cả đều tuyệt vời. Của tôi là template<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); } Nếu ai đó có câu trả lời đơn giản và dễ hiểu tương tự bằng cách sử dụng các loại có chữ ký, tôi rất muốn xem nó.
Ben Voigt

10

Trong ví dụ của bạn ở trên, khi 'i' sẽ luôn là số dương và phạm vi cao hơn sẽ có lợi, thì không dấu sẽ hữu ích. Giống như nếu bạn đang sử dụng câu lệnh 'khai báo', chẳng hạn như:

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

Đặc biệt là khi những giá trị này sẽ không bao giờ thay đổi.

Tuy nhiên, nếu bạn đang thực hiện một chương trình kế toán mà mọi người vô trách nhiệm với tiền của họ và thường xuyên ở trong tình trạng đỏ, bạn chắc chắn sẽ muốn sử dụng 'đã ký'.

Tôi thực sự đồng ý với thánh mặc dù một quy tắc ngón tay cái tốt là sử dụng có chữ ký, mà C thực sự mặc định, vì vậy bạn được bảo vệ.


9

Tôi nghĩ rằng nếu trường hợp kinh doanh của bạn quy định rằng một số âm là không hợp lệ, bạn sẽ muốn có một lỗi hiển thị hoặc ném ra.

Với ý nghĩ đó, tôi chỉ mới tìm hiểu về các số nguyên không dấu trong khi làm việc trong một dự án xử lý dữ liệu trong tệp nhị phân và lưu trữ dữ liệu vào cơ sở dữ liệu. Tôi đã cố tình "làm hỏng" dữ liệu nhị phân và cuối cùng nhận được các giá trị âm thay vì lỗi như mong đợi. Tôi nhận thấy rằng ngay cả khi giá trị được chuyển đổi, giá trị đó không hợp lệ cho trường hợp kinh doanh của tôi.
Chương trình của tôi không bị lỗi và cuối cùng tôi đã đưa dữ liệu sai vào cơ sở dữ liệu. Sẽ tốt hơn nếu tôi đã sử dụng uintvà chương trình bị lỗi.


8

Các trình biên dịch C và C ++ sẽ tạo ra một cảnh báo khi bạn so sánh các kiểu có dấu và không dấu; trong mã ví dụ của bạn, bạn không thể làm cho biến vòng lặp của mình không có dấu và để trình biên dịch tạo mã mà không có cảnh báo (giả sử đã bật cảnh báo).

Đương nhiên, bạn đang soạn thảo với các cảnh báo đã tăng lên, phải không?

Và, bạn đã cân nhắc việc biên dịch với "coi cảnh báo là lỗi" để tiến thêm một bước nữa không?

Nhược điểm của việc sử dụng số có dấu là có một sự cám dỗ để quá tải chúng, ví dụ: các giá trị 0-> n là lựa chọn menu và -1 có nghĩa là không có gì được chọn - thay vì tạo một lớp có hai biến, một để cho biết nếu cái gì đó được chọn và cái khác để lưu trữ lựa chọn đó là gì. Trước khi bạn biết điều đó, bạn đang kiểm tra âm tính ở khắp nơi và trình biên dịch đang phàn nàn về cách bạn muốn so sánh lựa chọn menu với số lựa chọn menu mà bạn có - nhưng điều đó nguy hiểm vì chúng khác loại . Vì vậy, đừng làm điều đó.


6

size_tthường là một lựa chọn tốt cho việc này, hoặc size_typenếu bạn đang sử dụng lớp STL.


Chỉ khi bạn xử lý kích thước của một thứ gì đó tính bằng byte.
mk 12

@ mk12 Vùng chứa Thư viện tiêu chuẩn hiển thị size_typethành viên với số lượng phần tử, không chỉ byte. Nó nên được sử dụng thay vì std::size_tkhi có sẵn, nhưng nó không chính xác khi ngụ ý rằng bất cứ thứ gì bắt đầu bằng size_tchỉ có thể có nghĩa là byte.
underscore_d
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.