C語言筆記之資料類型(一)

來源:互聯網
上載者:User

標籤:

在《電腦眼裡的數字》這篇文章中,我曾提到,位元組是電腦最小的可定址的單位,地址對應的是一個個位元組,而不是位元組的每個位。這樣編址的原因很簡單——單個的位所能表示的資訊量太少了,只有兩種狀態0和1,只有把足夠多的位組合起來才能表示足夠豐富的資訊。那麼為什麼一定要是8呢?因為大家都這麼做。。。好吧,肯定一定的曆史原因,我就不深究了。

但是,即使是8個位組成的位元組,其所能表示的資訊量仍然是有限的,因為最多隻有256中狀態組合,如果用每種狀態對應0~255之間的數位話,那麼就無法表示256這個數。這時候只好用兩個位元組來表示大於255的數。同樣的道理,當數字大到超過兩個位元組所能表示的數的極限後,就用四個位元組。。。是的,你也發現了,位元組數目總是翻倍增長,為什麼不用3個位元組呢?甚至,為啥不用1.5個位元組呢?對於前者,是因為考慮到對齊的原因,這其中有太多東西要說,我就不展開了;而後者,前面其實說到了,因為沒有位的編址,無法深入到位元組內部把資料揪出來。。所以,儲存肯定會有一定的浪費,在所難免。


上面羅嗦了那麼多,其實只是為了引出本文的豬腳——C語言資料類型,為什麼C語言要分那麼多類型呢?因為對於不同大小的數,所需要的儲存空間大小不同。如果都用4個位元組儲存,那麼肯定不用分資料類型,但是好浪費哦~所以,本著節省記憶體的考慮,資料類型就誕生了。C的資料類型分為基礎資料型別 (Elementary Data Type)和複合資料型別,後者只是前者的某種組合。基礎資料型別 (Elementary Data Type)按照其在電腦中的儲存方式又分為整數類型和浮點數類型。


一、整數類型

整數類型包括char、short、int、long、long long,它們沒有小數部分。char雖然是字元類型,但是由於儲存的是ASCII碼,本質上也是按整數儲存的,所以歸為這一類。不同的整數類型具有不同的位元組數,從而所佔用的儲存空間不同。然而,這一點是不確定的,準確的位元組數依賴於具體的機器和編譯器——機器不僅分品牌,還有32位和64位之分。下面的表格給出不同類型所佔有的典型的位元組數(來源《深入理解電腦系統》):

類型 32位機器 64位機器
char 1 1
short 2 2
int  4 4
long 4 8
long long 8 8
char * 4 8
float 4 4
double 8 8


注意,上表只是典型值,以32位為例:在有的機器上,short和int都是2個位元組,long是4個位元組;而有的機器上,short是2個位元組,而int和long是4個位元組。C語言僅僅規定:short <= int <= long,然後char是1個位元組。不過,對於大部分機器,上表夠用了。要查看自己機器上每種類型所佔的位元組數,請用sizeof(類型)來查看。

對於整數類型,C還用了signed和unsigned來修飾它們,以獲得有符號數和無符號數,預設時,認為是有符號數。正如在《電腦眼裡的數字》中提到的那樣,有符號數和無符號數的二進位表示可能是一樣的,區別僅僅是解讀方式。

有了各種類型之後(即位元組數確定之後),就可以規定它們所表示的數的範圍。下表是32位機器各種類型的典型取值範圍:

  signed unsigned
char -128 ~ 127 0 ~ 255
short -32768 ~ 32767 0 ~ 65535
int  -2147483648 ~ 2147483647 0 ~ 4294967295
long -2147483648 ~ 2147483647 0 ~ 4294967295
long long -9223372036854775808 ~ 9223372036854775807 0 ~ 18446744073709551615


這些界限值可以通過包含limits.h標頭檔加以查看,比如對於int值的各種範圍,可以通過列印INT_MAX  INT_MIN  

UINT_MAX UINT_MIN 來查看。


我們用幾個例子來看一下相同類型之間signed和unsigned的轉換。

1、將signed強制轉換成unsigned:

<span style="font-size:18px;">#include <stdio.h>int main(void){    int a = -1;     unsigned int b = (unsigned int)a;    printf("a = %d, b = %d\n", a, b);     printf("a = %u, b = %d\n", a, b);     printf("a = %d, b = %u\n", a, b);     printf("a = %#x, b = %#x\n", a, b);     return 0;}</span>

運行結果如下:

<span style="font-size:18px;">a = -1, b = -1a = 4294967295, b = -1a = -1, b = 4294967295a = 0xffffffff, b = 0xffffffff</span>

可以明顯的看出,將一個負數強制轉換為無符號數,並沒有改變其位元模式(二進位表示),它仍然按照原來的模樣儲存,第四行的結果證明了這一點;而前三行的結果表明,即使不做signed到unsigned的強制類型轉換,只需要在列印時改變一下輸出格式,就能達到同樣的效果。(這裡我開始懷疑把一個變數聲明為unsigned有啥意義?)


而將一個有符號的正數轉換為同類型的無符號數又如何呢?

2、將unsigned強制轉換成signed:

<span style="font-size:18px;">#include <stdio.h>int main(void){    unsigned short a = 32767;    short b = (short)a;    printf("a = %u, b = %u\n", a, b);     printf("a = %u, b = %d\n", a, b);     printf("a = %d, b = %u\n", a, b);     printf("a = %#x, b = %#x\n", a, b);     return 0;}</span>
結果如下:

<span style="font-size:18px;">a = 32767, b = 32767a = 32767, b = 32767a = 32767, b = 32767a = 0x7fff, b = 0x7fff</span>
可以看出,當一個非負數處於0~TMax(TMax代表某一類型有符號數的最大值)的範圍時,無論把它的二進位表示解讀成signed還是unsigned,結果都是一樣的。這是因為,處於這部分範圍內的數,轉換成二進位時,最高為都為0,如果按signed解讀,它是一個正數,數字部分就是7fff,;而按unsigned解讀,07fff == 7fff,結果總是一樣的。

那如果正數的範圍超過了TMax呢?

<span style="font-size:18px;">#include <stdio.h>int main(void){    unsigned int a = 2147483648u;    int b = (int)a;    printf("a = %u, b = %d\n", a, b);     printf("a = %d, b = %u\n", a, b);     printf("a = %#x, b = %#x\n", a, b);     return 0;}</span>

結果:

<span style="font-size:18px;">a = 2147483648, b = -2147483648a = -2147483648, b = 2147483648a = 0x80000000, b = 0x80000000</span>
可以看到,底層的二進位表示仍然是一致的,只是解讀方式發生了變化:由於最高位是1,所以解讀成signed時,是一個負數;解讀成unsigned仍然是正數,結果不同。

注意:因為變數分為signed和unsigned,對應的常量也要分為signed和unsigned;類型前沒有修飾時,預設為signed,對應的,一個常量數字預設為signed,即有符號數。如果希望一個常量數字被當成無符號數,就要在其末尾添加字母‘u‘或‘U’。

C語言筆記之資料類型(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.