深度剖析資料在記憶體中的儲存

2021-09-24 01:07:38 字數 3311 閱讀 7921

我們要想知道資料如何在記憶體中的儲存,就必須先談談資料型別的意義

(1) 如果我們把記憶體看成乙個個房間,那麼資料型別就決定了房間號和房間大小,這樣應該很好理解了吧!

接下來我們來談談資料型別的分類

(1)整形家族:

char // 有符號字元型,只不過把signed省略了

unsigned char //無符號型別字元型

signed char short // 有符號型別字元型

short //有符號短整型

unsigned short [int] //無符號短整型

signed short [int] //有符號短整型

int 有符號整型

unsigned int 有符號短整型

signed int 有符號整型

long 有符號長整型

unsigned long [int] 無符號長整型

signed long [int]有符號長整型

(2)浮點數家族:

float //單精度浮點型

double //雙精度浮點型

(3)構造型別

陣列型別

結構體型別 struct

列舉型別 enum

聯合型別 union

(4)

int *pint;

char *pc;

float * pf;

void * pv;

其中void * 表示空型別,通常應用於函式的返回型別、函式的引數、指標型別。

首先我們來談談整形在計算機中如何儲存的?

計算機中的有符號數有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號 位都是用0表示「正」,用1表示「負」,而數值位,三種表示方法各不相同

正數的原碼,反碼,補碼都是自身

負數的反碼是符號位不變,其它位取反, 反碼+1=補碼

而在我們計算機中對於整形來說:資料存放記憶體中其實存放的是補碼。有了上面的知識,我們就來做幾個例題來剖析一下吧。

char a=-1;

signed char b=-1;

unsigned char c=-1;

printf("a=%d,b=%d,c=%d",a,b,c);

-1的原碼為 10000000 00000000 00000000 00000001

-1反碼為 111111111 111111111 111111111 111111110

-1補碼為 111111111 111111111 111111111 111111111

又因為a是有符號char型別,在記憶體中佔乙個位元組,而int是佔4個位元組,這是會發會發生截斷,把-1補碼的後8位賦給a ,a在記憶體中就為 11111111

然後又把a按有符號10進製輸出,這時會把char 隱式型別轉換為int ,轉換規則為有符號位補符號位,無符號位補0,此時應補符號位 就得到了

111111111 111111111 111111111 111111111 然後以有符號10進製形式讀出來

告訴大家個小技巧,當為有符號型別時,這樣直接看補碼不好出來結果,所以先轉為原碼再讀,就能的到正確結果了 ,所以a,b輸出都為-1;

而c是無符號型別,所以要前面補0,就得到了

00000000 00000000 00000000 11111111 再轉為原碼讀出來就是答案了 即255

再來看乙個典型例題

char a = -128;   

printf("%u\n",a);

首先 按我們上一題的思路來繼續分析

-128的原碼 10000000 00000000 00000000 10000000

-128的反碼 11111111 11111111 11111111 01111111

-128的補碼 11111111 11111111 11111111 10000000

然後把-128的後八位二進位制賦給有符號a 所以得到a為 10000000

然後把a隱式型別轉換為 int

11111111 11111111 11111111 10000000 然後又按無符號型別10進製來讀,即按正數來讀。

128原碼 00000000 00000000 00000000 10000000

128反碼 00000000 00000000 00000000 10000000

128補碼 00000000 00000000 00000000 10000000

然後把128賦給a得到了10000000

然後把a隱式型別轉換轉為int 11111111 11111111 11111111 10000000

然後按無符號型別輸出

結果跟-128一樣,是不是很懷疑人生

來我們來看下乙個

char a[1000];     

int i;

for(i=0; i<1000; i++)

printf("%d",strlen(a));

首先strlen 是求字串長度得函式 , 遇到』\0』就結束,所以我們要找到當i為何值時,a[i]為0;

-1得補碼為 111111111 111111111 111111111 111111111

又因為a為乙個有符號char型別,所以會發生截斷,把後8位來賦值給a[i]

-1-1 為 11111111減到00000000中間的個數就為結果 255.

最後來說一下什麼是大小端。

計算機得記憶體是按從低位址到高位址這樣得順序排列的,而大端就是比較符合人類思維,低位存在記憶體高位上,

而小端則是低位存在低位址上。

//如果是小端就返回1,否者返回0; 

int islittleend()

return 1;

}

判斷大小端的函式如上。

剖析資料在記憶體中的儲存

乙個變數的建立是要在記憶體中開闢空間的,空間的大小是根據及不同的型別所決定的。在討論資料在所開闢記憶體中是如何儲存的之前要了解以下概念。例 答案 1,1,255 解析 首先要進行整形提公升,提公升時,要看自己的型別,有符號新增 1 無符號則新增 0 要看變數的型別 確定是否有符號位 若為無符號位,直...

C語言(九) 深度剖析資料在記憶體中的儲存 (下)

今天我們繼續來學習資料在記憶體中的儲存 c c 程式記憶體的分配 乙個由c c 編譯的程式占用的記憶體分別為一下幾個部分 1 棧區 stack 由編譯器自動分配釋放,存放為執行函式而分配的區域性變數 函式引數 返回資料 返回位址等。其操作方式類似於資料結構中的棧。2.堆區 heap 一般由程式設計師...

深度剖析資料在記憶體中的儲存(整型和浮點型)

我們知道乙個變數的建立是要在記憶體中開闢空間的,空間的大小是根據不同的型別而決定的,而且不同的型別也影響著我們看待記憶體空間的視角。比如 int a 20,float b 5.0 接下來我們看看資料在所開闢的型別中是如何儲存的?整型家族 char unsigned char,signed char ...