1. 程式人生 > >有符號數和無符號數------c++程序設計原理與實踐(進階篇)

有符號數和無符號數------c++程序設計原理與實踐(進階篇)

效果 進階 str 二進制位 bsp () 都是 有符號 重新

有符號數與無符號數的程序設計原則:

  • 當需要表示數值時,使用有符號數(如 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

-1)時,下一次增1運算不會得到更大的整型值,而會得到一個負數。因此循環永遠也不會停止!每當我們到達最大整數時,接著就會從最小負int值重新開始。因此如果v.size()的值為32*1024或者更大,循環變量為16位int型的話,這個循環就是一個(可能非常嚴重的)bug。如果循環變量是32位int型的話,當v.size()的值大於等於2*1024*1024*1024時就會出現同樣的問題。

為了避免這個問題,我們可以使用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++程序設計原理與實踐(進階篇)