從邏輯角度來看,使用int
爲數組索引更爲正確。
unsigned
C和C++中的語義並不真正意味着「不是負面」,而更像是「位掩碼」或「模整數」。
要理解爲什麼unsigned
是不是一個很好的類型爲「非負」數請考慮
- 添加可能爲負整數到非負整數你會得到一個非負整數
- 兩個非負整數的差異始終是一個非負整數
- 由負整數乘法非負整數你會得到一個非負結果
很明顯,上述短語沒有任何意義......但C和C++語言的確是如此。
實際上,使用容器大小的unsigned
類型是C++的一個設計錯誤,不幸的是我們現在註定要永遠使用這個錯誤的選擇(爲了向後兼容)。你可能會喜歡「unsigned」這個名字,因爲它與「非否定」類似,但名稱無關緊要,重要的是語義......而且unsigned
與「非否定」非常相似。
爲此編碼的載體大多數循環時,我個人傾向於形式是:
for (int i=0,n=v.size(); i<n; i++) {
...
}
(當然假設矢量大小的迭代過程中沒有改變,而我實際需要的指數在身體,否則for (auto& x : v)...
更好)。
儘快從unsigned
跑開,使用普通整數有避免因設計錯誤unsigned size_t
造成的陷阱的優勢。例如,考慮:
// draw lines connecting the dots
for (size_t i=0; i<pts.size()-1; i++) {
drawLine(pts[i], pts[i+1]);
}
上面的代碼中會出現問題,如果pts
向量是空的,因爲pts.size()-1
在這種情況下,一個巨大的廢話數。處理a < b-1
與a+1 < b
不一樣的表達方式,即使對於常用的值,也像是在雷區中跳舞。
從歷史上看,size_t
無符號的理由是爲了能夠使用額外的比特作爲值,例如,能夠在陣列中擁有65535個元素,而不是在16位平臺上擁有32767個元素。在我看來,即使在那個時候,這個錯誤的語義選擇的額外成本也不值得(但如果32767個元素不夠用,那麼65535就不夠長)。
無符號值很好,非常有用,但不代表容器大小或索引;對於規模和索引規則有符號整數的工作要好得多,因爲語義是你期望的。
當您需要模運算屬性或想要在位級別工作時,無符號值是理想的類型。
這是寫少。 – slartibartfast
另外:更具可讀性 – Alex
這就好比你爲什麼不總是打電話給其他人姓名,而只是叫他們的名字? – user482594