有符號和無符號數據類型


原版出處:http://bbs.csdn.net/topics/340253678

C語言中提供了很多整數類型(整型),主要區別在於它們取值范圍的大小。int代表有符號的整數,也就是說,用int聲明的變量可以是正數也可以是負數,也可以是零,但是只能是整數。
比如:int a = 3; int b = 0; int c = -5;
以上這些都是合法的。
int的取值范圍因機器而異,一般而言,在較舊的PC上,int值在內存中一般是按2個字節(16位)進行存儲的,在較新的PC以及工作站和大型機上,int值在內存中一般是按照4個字節(32位)進行存儲的。


C語言中將基本數據類型划分為signed(有符號)和unsigned(無符號)兩大類。
例如,初始化變量int a = -3;其實它等價於signed int a = -3;關鍵字signed在這里可以省略,因為C語言默認就是有符號類型的,如果要定義無符號類型的數(也就是0和正整數)可以這樣定義,unsigned int b = 5;

為了說明清楚signed和unsigned的區別,首先需要了解數據在內存中是如何存儲的,在計算機中所有的數據都是按照二進制進行存儲的(以下假設在字長為2個字節的機器上來表示)。

舉個例子來說,unsigned  int a = 1; 變量a在內存中就是以00000000 00000001來存儲的,用圖表的形式表示:



因為這里是unsigned  int,它是無符號整型,所以的它的16位全部用來表示數據。

int b = -1;

這里情況就稍微有點復雜了,注意數字1和-1在內存中的存儲是完全不一樣的,請看,

在計算機中,整數是以原碼的形式存儲的,而負數是以補碼的形式存儲的,原碼大家都知道也就是它對應的二進制碼,那什么是補碼呢,就是原碼的反碼加1,反碼就是原碼的各位取反,例如-1的補碼是:

首先1的原碼是                     00000000 00000001

其次取它的反碼是                 11111111 11111110

最后在其反碼的基礎上加上1   11111111 11111111

得到-1的補碼是,11111111 11111111

用圖表的形式表示:

http://hi.csdn.net/attachment/201008/11/0_1281514535se1Q.gif

從上圖中可以看出,int用15位來表示一個數字,第1位被符號位占用了,其實大家應該不難看出在數學中-1是負數中最大的整數,所以這里看到它的各個位都置1,對應於二進制來講就是最大的數了,計算機就是按照符號位來識別該數是正是負,所以第一位只起到標識的作用並不作為數據位來使用,而其余的15位才是真正的數據位。以補碼的形式來存儲有個好處那就是計算機將負數的運算當作加法來處理了。那么將一個有符號的數賦給一個無符號的數會發現一個很有趣的現象,比如:

unsigned int a;

int b = -1;

a = b;

printf("a=%u",a);

輸出a=65535,這個結果是怎么出來的呢?其實很簡單,b=-1,根據上圖-1在計算機中的數據位是1111111 11111111,注意是數據位,是要去掉符號位的,所以是15位,a是無符號類型的整數,將b賦給a,自然a就是1111111 11111111,也是15位第一位補0,轉換成十進制就是65535,它也是unsigned int范圍的最大上限(0~65535 216-1),-1是最大的負整數轉換成正整數當然也是最大了,這個應該很好理解了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM