2009-10-12 68 views
18

當用類似C的語言進行編程時,應該將「默認」整數類型設爲int或uint/unsigned int?默認情況下,我的意思是當你不需要負數時,但是任何一個數據都應該足夠容納你所持有的數據。我可以想到兩個很好的論點:默認int類型:有符號或無符號?

signed:在數學上更好的表現,如果你在沒有想到的邊界情況下嘗試低於零,那麼奇怪行爲的可能性就會降低,通常會避免奇怪的邊角情況。

unsigned:提供一點額外的保證來防止溢出,以防萬一你對這些值的假設是錯誤的。作爲文檔,變量所代表的值應該爲從不爲爲負數。

回答

13

Google C++ Style Guide對無符號整數一個有趣的觀點:

(報價如下:)

在無符號整數

一些人,包括一些教科書作者,推薦使用無符號類型來表示從不消極的數字。這是作爲一種自我記錄的形式。但是,在C語言中,這種文檔的優勢超過了它可以引入的實際錯誤。考慮:

for (unsigned int i = foo.Length()-1; i >= 0; --i) ... 

此代碼將永不終止!有時gcc會注意到這個錯誤並警告你,但通常情況下它不會。在比較有符號和無符號變量時,同樣會出現錯誤。基本上,C的類型提升方案會導致無符號類型的行爲與預期不同。

因此,使用斷言來記錄一個變量是非負的。不要使用無符號類型。

(完報價)

+6

實際上,我認爲C的類型提升方案會導致* signed * ints的行爲與預期不同。無符號整數表現得很好,如果您知道模算術,而signed int具有依賴於實現的行爲和遍佈整個地方的有趣轉換。但是如果你只打算使用一個,爲了避免混淆它,它必須被簽名。所以我同意這樣一個結論,即不應該使用unsigned int,但實際上我認爲不應該使用下行循環... – 2009-10-12 15:50:36

+2

GCC無法警告它已經很長時間了無符號> = 0'總是如此。谷歌指南最好是誤導性的,在最壞的情況下是危險的,因爲循環迭代器的一個非常常見和非常正確的類型將是無符號類型'size_t'。當使用零原點計數器向後計數時,正確的無符號下溢測試是'i!=〜0U'。 – 2016-03-04 22:27:12

3

我傾向於去有符號的,除非我知道我需要簽名,作爲int通常都有簽名,這需要更多的努力來鍵入unsigned int,並uint可能會導致另一個程序員輕微的停頓思考什麼值可以爲。

所以,我沒有看到任何好處,只是默認爲無符號,因爲正常的int被簽名。

+2

+1我會更強烈地陳述:大多數程序員的期望(特別是來自Java,比如說)是'int'是默認簽名的。在代碼中看到「int」並且它顯示未簽名的行爲會很奇怪。 – 2009-10-12 15:19:10

11

當然簽字。如果溢出令您擔心,下溢會讓您更加擔心,因爲偶然發生「低於零」比int-max更容易。

「無符號」應該是一個有意識的選擇,它可以讓開發人員考慮潛在的風險,只在那裏你絕對確信你永遠不會消極(甚至不會意外),並且你需要額外的價值空間。

+0

+1,謝謝,只是想問同樣的問題。這一點對我來說很重要:「...你需要額外的價值空間。」 – 2010-06-05 22:49:08

0

我懷疑有一個非常好的語言無關的答案。語言之間有足夠的差異,以及他們如何處理混合類型,所有人(甚至大多數人)都沒有人會回答這個問題。

在我最常使用的語言中,我使用簽名,除非我有其他特殊原因。這主要是C和C++。用另一種語言,我可能會給出不同的答案。

2

你沒有得到太多的「保證溢出」與unsigned。你很可能會得到不同但陌生的行爲,而不是稍微晚一點......最好能在事先得到這些假設之前呢?

+0

在C中,定義了無符號溢出;有符號溢出是* undefined *。這是「保證不溢出」給我。 – 2017-06-14 00:50:20

1

給出更具體的類型賦值(如unsigned int)可以傳遞更多關於變量使用情況的信息,並且可以幫助編譯器在分配「錯誤」值時隨時跟蹤。例如,如果您使用變量來跟蹤對象/元素的數據庫ID,那麼(有可能)不應該是ID小於零(或一個)的時間。在這種情況下,不是斷言該狀態,而是使用無符號整數值將該語句傳達給其他開發人員以及編譯器。

4

作爲一個粗略的經驗法則,我使用了無符號整數來計算事物,並簽署了用於測量事物的整數。

如果你發現自己遞減或從一個unsigned int減去,那麼你應該在你已經期望非常小心的上下文中不要下溢(例如,因爲你在一些低級代碼步進從一個字符串的末尾返回,所以當然你首先要確保字符串足夠長以支持這個)。如果你不在這樣的背景下,那麼你不應該低於零,那麼你應該使用一個有符號的值。

在我的使用中,無符號整數的值絕對不能爲負數(或者對於那些實際上需要模2^N算術的百萬情況下的值),不適用於不會發生負值的值,在目前的實施中,可能。

相關問題