C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)詳解
數(shù)據(jù)的存儲(chǔ)首先就要說(shuō)到數(shù)據(jù)的類型,類型決定了看待內(nèi)存空間的視角。
C語(yǔ)言的數(shù)據(jù)類型分為內(nèi)置類型和外置類型
1.內(nèi)置類型
(1)整型數(shù)組
char
(字符型)、short
(短整型)、int
(整型)、long
(長(zhǎng)整型)(signed
或者 unsigned
)
(2)浮點(diǎn)型
float
(單精度浮點(diǎn)型)、double
(雙精度浮點(diǎn)型)
2.自定義類型
(1)數(shù)組類型
此處需要注意的是,去掉數(shù)組名就是數(shù)組的類型
比如int arr[10],去掉數(shù)組名arr,int [10]就是數(shù)組數(shù)據(jù)類型
(2)結(jié)構(gòu)體類型(struct
)
(3)枚舉類型(enum
)
(4)聯(lián)合類型(union
)
3.指針類型
4.空類型(void)
數(shù)據(jù)的存儲(chǔ)形式就是以計(jì)算機(jī)的原碼反碼補(bǔ)碼進(jìn)行存儲(chǔ)的
浮點(diǎn)型:不以原反補(bǔ)的形式進(jìn)行存儲(chǔ)
其他的數(shù)字又分為有符號(hào)數(shù)和無(wú)符號(hào)數(shù)
無(wú)符號(hào)數(shù):無(wú)符號(hào)數(shù)的原反補(bǔ)三種碼是一致的,存儲(chǔ)的時(shí)候沒(méi)有區(qū)別
符號(hào)數(shù)來(lái):正數(shù)的原反補(bǔ)碼是相同的,但是負(fù)數(shù)的原反補(bǔ)碼需要經(jīng)過(guò)運(yùn)算轉(zhuǎn)化(正數(shù)的最高位是0,負(fù)數(shù)的最高位是1)
原碼:將二進(jìn)制按照正負(fù)數(shù)形式翻譯為二進(jìn)制數(shù)字
反碼:將原碼的每一位取反
補(bǔ)碼:反碼+1
存儲(chǔ)的時(shí)候一般存儲(chǔ)數(shù)字的二進(jìn)制序列補(bǔ)碼
同時(shí)數(shù)據(jù)的存儲(chǔ)存在大小端
內(nèi)存空間具有編號(hào),編號(hào)小的為低地址,編號(hào)大的為高地址
大端存儲(chǔ):數(shù)據(jù)的低位保存在內(nèi)存的高地址中
小端存儲(chǔ):數(shù)據(jù)的低位保存在內(nèi)存的低地址中
每個(gè)機(jī)器的存儲(chǔ)方式不同,可以用如下一段簡(jiǎn)單代碼來(lái)觀察電腦是哪一種存儲(chǔ)方式
#include<stdio.h> int main() { int a = 1; char* p = (char*)&a; //此處將整型地址強(qiáng)制轉(zhuǎn)化為字符型 //強(qiáng)制轉(zhuǎn)化并不影響地址的存儲(chǔ),只會(huì)影響讀取 //指針決定讀取內(nèi)存的位數(shù),字符型指針在解引用時(shí)只解1字節(jié),整型指針在解引用時(shí)解4字節(jié) //a存儲(chǔ)時(shí),a是正數(shù),原反補(bǔ)相同 //00000000 00000000 00000000 00000001 //指針在強(qiáng)制轉(zhuǎn)化為字符型之后只能讀取該內(nèi)存的前8位 //如果該指針解引用后結(jié)果是1,該數(shù)據(jù)存儲(chǔ)結(jié)果為00000001 00000000 00000000 00000000 //如果不是,該數(shù)據(jù)存儲(chǔ)結(jié)果為00000000 00000000 00000000 00000001 if (*p == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
字符型
char/signed char 所對(duì)應(yīng)的存儲(chǔ)區(qū)間為-128~127,同時(shí)規(guī)定10000000為-128。
為了理解signed與unsigned,適用如下例題
#include<stdio.h> int main() { unsigned int i; for (i = 9; i >= 0; i--) //在這個(gè)循環(huán)開(kāi)始之前就需要注意到,i需要小于0,該循環(huán)才會(huì)停止 //但是此時(shí)的i是一個(gè)unsigned類型,本身存儲(chǔ)的時(shí)候并沒(méi)有預(yù)留符號(hào)位,是沒(méi)有辦法破開(kāi)循環(huán)的 //該循環(huán)是死循環(huán) { printf("%d", i); } }
signed
與unsigned
的區(qū)別就在于能否表示正負(fù)數(shù)
在數(shù)據(jù)的存儲(chǔ)時(shí),是否存在符號(hào)位
signed char與char類型的存儲(chǔ)也可以用一個(gè)圖來(lái)說(shuō)明
中間的分界線即為正負(fù)分界線,第一位即為符號(hào)位。符號(hào)位為1是負(fù)數(shù),符號(hào)位為0即為正數(shù)
理解char的存儲(chǔ)范圍,借用如下例題
#include<stdio.h> #include<string.h> int main() { char a[1000]; int i; for (i = 0; i < 1000; i++) { a[i] = -1 - i; } printf("%d", strlen(a)); return 0; } //i是int類型,可以隨著循環(huán)不斷增長(zhǎng),但是對(duì)于a這個(gè)數(shù)組來(lái)說(shuō),能存儲(chǔ)的數(shù)據(jù)有限。 //數(shù)組a是字符型,字符型數(shù)組能存儲(chǔ)的范圍就是-128~127之間,一共255個(gè)數(shù),所以數(shù)組長(zhǎng)度也是255
運(yùn)行結(jié)果:255
int等類型的存儲(chǔ)方式與char相似,這里就不在多做贅述
利用一個(gè)例子來(lái)證明浮點(diǎn)型存儲(chǔ)與整型存儲(chǔ)不同
#include<stdio.h> int main() { int n = 9; float* pfloat = (float*)&n; printf("n的值為:%d\n", n); printf("*pfloat的值為:%f\n", *pfloat); //此處以單精度浮點(diǎn)型的指針取出存儲(chǔ)在整形中的數(shù)據(jù) *pfloat = 9.0; printf("n的值為:%d\n", n); printf("*pfloat的值為:%f\n", *pfloat); //此處通過(guò)單精度浮點(diǎn)型的指針更改原本存儲(chǔ)在整型中的數(shù)字,并將其更改為單精度浮點(diǎn)型數(shù)字 return 0; }
輸出結(jié)果:
n的值為:9
*pfloat的值為:0.000000
n的值為:1091567616
*pfloat的值為:9.000000
由此可見(jiàn),單精度浮點(diǎn)型的指針并不能成功取出原本存儲(chǔ)在整形中的數(shù)字,而第二步中通過(guò)單精度浮點(diǎn)型的指針?biāo)牡恼蔚闹担琻也無(wú)法成功取用,所打出來(lái)的數(shù)字并不是9。由此可見(jiàn)二者的存儲(chǔ)方式是存在較大差異的,所以下面對(duì)浮點(diǎn)型的存儲(chǔ)方式進(jìn)行講解。
浮點(diǎn)型
浮點(diǎn)型并不依靠數(shù)據(jù)的原反補(bǔ)碼進(jìn)行存儲(chǔ)
浮點(diǎn)型有其特殊的規(guī)定
(E也可以理解為最高此項(xiàng)所對(duì)應(yīng)的階次)
用實(shí)例來(lái)證明一下
比如8.5這個(gè)浮點(diǎn)數(shù)
轉(zhuǎn)化為二進(jìn)制
1000.1
對(duì)于這個(gè)數(shù)而言,存儲(chǔ)成圖中形式就是
(-1)^0*1.0001*2^3
存儲(chǔ)就是
0 00000011 00000000000000000010001
此時(shí)假設(shè)我們所申請(qǐng)到的內(nèi)存是一個(gè)條狀,那么對(duì)于浮點(diǎn)數(shù)而言的數(shù)據(jù)存儲(chǔ)方式如圖所示
?
?單精度浮點(diǎn)型對(duì)應(yīng)的就是圖一中所示,SME分布在不同的位置,圖二的所示為雙精度浮點(diǎn)型,雙精度與單精度浮點(diǎn)型所對(duì)應(yīng)的E與M不同。
(一)
就是E的值,既不能全為0,也不能全為1,且E的存儲(chǔ)值與真實(shí)值不相同
為了表示極小的小數(shù),比如1*10^-10,因?yàn)镋本身不具有符號(hào)位,所以不能表示負(fù)數(shù)
單精度:E=真實(shí)值+127
雙精度:E=真實(shí)值+1023
加完之后再轉(zhuǎn)化為二進(jìn)制存儲(chǔ)為E,拿出來(lái)使用的時(shí)候再將這個(gè)數(shù)字減去
特殊情況1:E為全0
單精度的E此時(shí)的真實(shí)值為-127,該浮點(diǎn)數(shù)幾乎等于0,是一個(gè)幾乎不存在的數(shù)字
特殊情況2:E為全1
單精度的E此時(shí)的真實(shí)值為128,該浮點(diǎn)數(shù)是為正負(fù)無(wú)窮大的數(shù)字
(二)
對(duì)于M來(lái)說(shuō),M的值既然是在區(qū)間【1,2)之間,則位于整數(shù)部分的肯定為1
再次利用單精度浮點(diǎn)型存儲(chǔ)8.5
該數(shù)字的M為1.0001
為了能讓浮點(diǎn)數(shù)表達(dá)更大的數(shù)字,且M中處于個(gè)位的數(shù)字固定為1,之后就規(guī)定,M中個(gè)位的1可以不再進(jìn)行存儲(chǔ),等到取用的時(shí)候再進(jìn)行添加。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- C語(yǔ)言二進(jìn)制思想以及數(shù)據(jù)的存儲(chǔ)
- C語(yǔ)言數(shù)據(jù)的存儲(chǔ)和取出詳細(xì)講解
- C語(yǔ)言詳細(xì)圖解浮點(diǎn)型數(shù)據(jù)的存儲(chǔ)實(shí)現(xiàn)
- C語(yǔ)言數(shù)據(jù)的存儲(chǔ)超詳細(xì)講解上篇
- C語(yǔ)言數(shù)據(jù)的存儲(chǔ)詳解
- C語(yǔ)言數(shù)據(jù)的存儲(chǔ)超詳細(xì)講解中篇練習(xí)
- 帶你了解C語(yǔ)言的數(shù)據(jù)的存儲(chǔ)
- 詳解C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)
- C語(yǔ)言中數(shù)據(jù)的存儲(chǔ)詳解
相關(guān)文章
c語(yǔ)言實(shí)現(xiàn)計(jì)算圓周率的近似值
這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)計(jì)算圓周率的近似值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Linux頁(yè)面置換算法的C語(yǔ)言實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Linux頁(yè)面置換算法的C語(yǔ)言實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12C++類中三大函數(shù)詳解(構(gòu)造、析構(gòu)和拷貝)
c++三大函數(shù)指的是拷貝構(gòu)造、拷貝賦值、析構(gòu)函數(shù),下面這篇文章主要給大家介紹了關(guān)于C++類中三大函數(shù)(構(gòu)造、析構(gòu)和拷貝)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03C++ 二叉搜索樹(shù)(BST)的實(shí)現(xiàn)方法
這篇文章主要介紹了C++ 二叉搜索樹(shù)(BST)的實(shí)現(xiàn)方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下2017-04-04win10環(huán)境下C++ vs2015編譯opencv249的教程
這篇文章主要介紹了win10環(huán)境下C++ vs2015編譯opencv249的教程,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03C語(yǔ)言實(shí)現(xiàn)掃雷游戲(含注釋詳解)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)掃雷游戲,含注釋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06vscode C++開(kāi)發(fā)環(huán)境配置步驟詳解(教你如何用vscode編寫(xiě)寫(xiě)C++)
這篇文章主要介紹了vscode C++開(kāi)發(fā)環(huán)境配置詳細(xì)教程(教你如何用vscode編寫(xiě)寫(xiě)C++),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03