有符號數和無符號數------c++程序設計原理與實踐(進階篇)
阿新 • • 發佈:2017-11-18
效果 進階 str 二進制位 bsp () 都是 有符號 重新 -1)時,下一次增1運算不會得到更大的整型值,而會得到一個負數。因此循環永遠也不會停止!每當我們到達最大整數時,接著就會從最小負int值重新開始。因此如果v.size()的值為32*1024或者更大,循環變量為16位int型的話,這個循環就是一個(可能非常嚴重的)bug。如果循環變量是32位int型的話,當v.size()的值大於等於2*1024*1024*1024時就會出現同樣的問題。
有符號數與無符號數的程序設計原則:
- 當需要表示數值時,使用有符號數(如 int)。
- 當需要表示位集合時,使用無符號數(如unsigned int)。
有符號數和無符號數混合運算有可能會帶來災難性的後果。例如:
vector<int> v; for(int i=0;i<v.size();++i)cout<<v[i]<<‘\n‘;
易實現版本:
unsigned char max=160; //非常大 for(signed char i=0;i<max;i++)cout<<int(i)<<‘\n‘;
循環變量i可能會溢出,即,v.size()有可能比最大的有符號數int值還要大。當i的值增大到有符號數int所能代表的最大正數(如,int為16位寬度,此值為215
為了避免這個問題,我們可以使用vector提供的size_tupe或者是叠代器:
for(vector<int>::size_type i=0;i<v.size();++i)cout<<v[i]<<‘\n‘; for(vector<int>::iterator p=v.begin();p!=v.end();++p)cout<<*p<<‘\n‘; for(int x:v)cout<<x<<‘\n‘;
size_tupe確保是無符號的,因此,第一種形式(使用無符號數)與int型循環變量的版本相比,多出一個二進制位來表示循環變量的數值(而不是符號)。這個改進很重要,但終究只是多出一位來表示循環的範圍(循環次數多出一倍)。而使用叠代器的版本就不存在這個限制。
大致來說,我們有兩個原因將無符號數當作整數來使用,而不是簡單作為一組二進制位(即,不使用+、-、*和/);
- 有更多的二進制位來表示數值,從而獲得更高的精度。
- 用來表示邏輯屬性,其值不能是負數。
前者就是我們剛剛看到的,使用無符號循環變量帶來的效果。
混合使用有符號數和無符號數的問題在於,在c++中,兩者轉換的方式很奇怪,而且難以記憶。例如:
unsigned int ui=-1; int si=ui; int si2=ui+2; unsigned ui2=ui+2;
輸出結果:
4294967295 -1 1 1
不推薦為獲得一個額外的二進制位的精度而是要無符號數。
標準庫容器的下標都是無符號數。
c++程序設計原理與實踐(進階篇)
有符號數和無符號數------c++程序設計原理與實踐(進階篇)