C語言數(shù)據(jù)存儲歸類介紹
數(shù)據(jù)類型的介紹
在前面的章節(jié)中我們基本認(rèn)識到了各種數(shù)據(jù)類型,這里我們就稍微回憶以下吧
類型的意義:
- 決定了訪問內(nèi)存空間的大小
- 決定了看待內(nèi)存空間的視角(例如:整型和字符數(shù)據(jù)類型)
類型的基本歸類
整型家族:
char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
浮點型家族:
float
double
構(gòu)造類型:
> 數(shù)組類型
> 結(jié)構(gòu)體類型 struct
> 枚舉類型 enum
> 聯(lián)合類型 union
指針類型:
int *pi; char *pc; float *pf; void *pv;(泛型指針)
空類型:
void 表示空類型 (無類型)
通常用于 函數(shù)的返回類型、函數(shù)的參數(shù)、指針類型
//作為函數(shù)的返回類型 void f1()//不接受任何返回值 { ; } //作為函數(shù)的參數(shù) int f2(void)//參數(shù)為void時,傳入?yún)?shù)會報錯 { ; } //作為指針類型 void* f3(void* pv)//參數(shù)為 void* 時,可接收任意類型的參數(shù) { ; }
整型在內(nèi)存中的存儲
計算機(jī)中的整數(shù)有三種2進(jìn)制表示方法,即源碼、反碼、補(bǔ)碼。
三種表示方法均有符號位和數(shù)值位
符號位: " 0 " 表示 正," 1 "表示 負(fù)
數(shù)值位:
正數(shù):
原碼、反碼、補(bǔ)碼相同
負(fù)數(shù):
原碼:直接將數(shù)值按二進(jìn)制翻譯
反碼:原碼符號位不變,其它位按位取反
補(bǔ)碼:反碼+1
我們可以在內(nèi)存中的存儲看到:
這里大家可能有個疑問,為什么j
和i
在內(nèi)存中會是這樣?為什么i
和 j
內(nèi)部二進(jìn)制會倒過來存儲呢??編譯器壞了???(bushi
如果對此事好奇,就接著往下看吧。
什么是大小端
大小端存儲是計算機(jī)的一種存儲方式,其主存儲的方式也由計算機(jī)決定。
什么是大小端存儲:
大端(存儲)模式:指的是,數(shù)據(jù)的低 (二進(jìn)制)位保存在高地址中,高位保存在低地址中;
小端(存儲)模式:指的是,數(shù)據(jù)的低位保存在低地址中,高位保存在高地址中;
注意:
大小端存儲只跟單個類型數(shù)據(jù)的存儲方式有關(guān),數(shù)組的存儲依然是由低地址向高地址進(jìn)行存儲
浮點數(shù)在內(nèi)存中的存儲
在認(rèn)識浮點數(shù)在內(nèi)存中的存儲之前,我們先看一下下面的例子:
int main() { int n = 9; float* pf = (float*)&n; printf("n的值為:%d\n", n); printf("pf的值為:%f\n", *pf); *pf = 9.0; printf("n的值為:%d\n", n); printf("pf的值為:%f\n", *pf); return 0; }
為什么輸出結(jié)果會是這樣?
想要了解其中的原因我們首先要知道浮點數(shù)在內(nèi)存中的存儲規(guī)則
浮點數(shù)在內(nèi)存中的存儲規(guī)則
浮點數(shù)存儲根據(jù)國際標(biāo)準(zhǔn) IEEE (電氣工程師學(xué)會) 754 來進(jìn)行存儲,具體規(guī)則如下:
- (-1)^S * M * 2^E
- (-1)^S 代表 符號位,S=0為正數(shù),S=1為負(fù)數(shù)
- M 表示有效數(shù)字,(1 ≤ M < 2)
- 2^E表示指數(shù)位
IEEE 754規(guī)定:
對于 float
類型來說:
對于 double
類型來說:
IEEE 754對 有效數(shù)字M 和 指數(shù)E 有一些特殊的規(guī)定:
有效數(shù)字M
前面說過,1 ≤ M < 2
,也就是說,M可以寫成 1.xxxxxx
的形式,將 小數(shù)點前省略,則其中xxxxxx
就是我們所要保存的數(shù)字
指數(shù)E
對于 float
類型(E 占 8 位):E + 127
(取 0~255 中間數(shù))
對于 double
類型(E 占 11 位):E + 1023
(取 0~2047 中間數(shù))
舉個例子(o?v?)ノ
十進(jìn)制的 5.0
想要存進(jìn)去
小數(shù)點前 需要轉(zhuǎn)換成 二進(jìn)制 101 . 0
根據(jù)科學(xué)計數(shù)法將其轉(zhuǎn)換,1.01 x 2^(2)
指數(shù)E 進(jìn)行替換 E = 2+127 = 129 = 1000 0001(二進(jìn)制)
由上可得出 S = 0
E = 1000 0001
M = 1.01
0 10000001 01000000000000000000000
S E M整理一下:
0100 0000 1010 0000 0000 0000 0000 0000
用十六進(jìn)制表示:
4 0 a 0 0 0 0 0
整理一下:(大端存儲)
40 a0 00 00
小端存儲:
00 00 a0 40
趁著手還熱乎,趕緊再來看看吧(/≧▽≦)/
十進(jìn)制 -2.25
在內(nèi)存中如何存儲?
- 符號為負(fù)
S = 1
- 小數(shù)點前正著寫二進(jìn)制,小數(shù)點后按照
2^(-n)
,n = 4 (1/4=0.25),(倒著寫二進(jìn)制),所以二進(jìn)制為10.01
- 用科學(xué)計數(shù)表示
1.001 x 2^(1)
- 指數(shù)E進(jìn)行替換
E = 1 + 127 = 128 = 1000 0000(二進(jìn)制)
- 由上可得
S = 1
E = 1000 0000
M = 1.001
1 10000000 00100000000000000000000
S E M整理一下:
1100 0000 0001 0000 0000 0000 0000 0000
用十六進(jìn)制表示:
c 0 1 0 0 0 0 0
整理一下:
c0 10 00 00
小端存儲:
00 00 10 c0
注意:(特殊情況)
當(dāng)指數(shù)E為邊界值時 0~255(0~1023)直接等于具體的真實值
E全為0:
直接等于0
E全為1:
直接等于具體值340282346638528859811704183484516925440.000000(2^255)
到此這篇關(guān)于C語言數(shù)據(jù)存儲歸類介紹的文章就介紹到這了,更多相關(guān)C語言數(shù)據(jù)存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++ Crypto密碼庫調(diào)用的實現(xiàn)方法
Crypto 庫是C/C++的加密算法庫,這個加密庫很流行,基本上涵蓋了市面上的各類加密解密算法,感興趣的可以參考一下2021-06-06C++有限狀態(tài)機(jī)實現(xiàn)計算器小程序
這篇文章主要為大家詳細(xì)介紹了C++有限狀態(tài)機(jī)實現(xiàn)計算器小程序的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06c語言中十六進(jìn)制轉(zhuǎn)二進(jìn)制顯示的實現(xiàn)方法
本篇文章對c語言中十六進(jìn)制轉(zhuǎn)二進(jìn)制顯示的實現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C++實現(xiàn)二叉樹非遞歸遍歷方法實例總結(jié)
這篇文章主要介紹了C++實現(xiàn)二叉樹非遞歸遍歷方法實例總結(jié),是算法設(shè)計中比較經(jīng)典的一個遍歷算法,需要的朋友可以參考下2014-08-08C++基于socket多線程實現(xiàn)網(wǎng)絡(luò)聊天室
這篇文章主要為大家詳細(xì)介紹了C++基于socket多線程實現(xiàn)網(wǎng)絡(luò)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07