有符號變數與無符號變數的值的轉換

2021-08-18 14:35:36 字數 2467 閱讀 5770

最近了解了一下有符號變數與無符號變數的區別和聯絡,看下面**:

#include 

char

getchar (

intx,

inty)  

intmain (

void

)    

程式輸出結果為:

c1 = 1;

c2 = 2;

c3 = 1;

c4 = 2;

首先說明getchar()函式的作用:將引數x的值轉換為無符號整形後再與y相加。其結果與101進行比較,如果大於10則函式返回1,否則返回2。

注意:當表示式中存在有符號型別和無符號型別時,所有的運算元都自動轉換為無符號型。

因此y值會首先自動轉換成無符號的整數,然後和a相加,最後再與10進行比較。

以下是列印的各個值的分析:

c1:傳入引數分別為7和4,兩個數相加後為11,大於10,c1返回1;

c2:傳入引數分別為7和-7,負數在轉為無符號整數數時會先求出其補碼,在32位的編譯器中,-7的原碼為1000 0000 0000 0000 0000 0000 0000 0111,

補碼為1111 1111 1111 1111 1111 1111 1111 1001,7的補碼為0000 0000 0000 0000 0000 0000 0000 0111,相加再轉換為十進位制為4294967296,而無符號整形的範圍 為

0~4294967295,顯然溢位了1,其最終值為0,0小於10,所以c2 = 2;

c3:傳入引數分別為7和-8,同上,a+y = 4294967295 ,剛好達到無符號整型的極限,大於10,所以c3 = 1;

c4:傳入引數分別為-6和7,同上,a+y = 4294967297,溢位2,其最終值為1,小於10,所以c3 = 2;

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

用圖表的形式表示:

從上圖中可以看出,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是最大的負整數轉換成正整數當然也是最大了,這個應該很好理解了。

參考文章:

有符號變數與無符號變數的值的轉換

include char getchar int x,int y int main void 這段程式的輸出結果為 c1 1 c2 2 c3 1 c4 2 首先說明getchar 函式的作用 將引數x的值轉換為無符號整形後再與y相加。其結果與101進行比較,如果大於10則函式返回1,否則返回2。注意...

有符號變數與無符號變數的值的轉換

知識點 原碼和補碼,在計算機系統中,數值一律用補碼來表示和儲存 正數的補碼 與原碼相同 負數的補碼 符號位為1,其餘位為該數絕對值的原碼按位取反,然後加1 例如,乙個char型別的 7的補碼 因為是負數,則符號位為 1 整個為10000111 其餘7位為 7的絕對值 7的原碼 0000111按位取反...

有符號與無符號

最高位為1,表示這個數為負數 最高位為0,表示這個數為正數 include int main 執行結果 正數的補碼為正數本身 負數的補碼為負數的絕對值各位取反後加1 8位整數5的補碼為 0000 0101 8位整數 7的補碼為 1111 1001 16位整數20的補碼為 0000 0000 0001...