国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

C語言進(jìn)階第一問:數(shù)據(jù)在內(nèi)存中是如何存儲的?(手把手帶你深度剖析數(shù)據(jù)在內(nèi)卒中的存儲,超全解析,碼住不

ghnor / 2335人閱讀

摘要:在符號位中,表示正,表示負(fù)。我們知道對于整型來說,內(nèi)存中存放的是該數(shù)的補(bǔ)碼。在計算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示和存儲。表示有效數(shù)字,。規(guī)定對于位的浮點(diǎn)數(shù),最高的位是

最近博主開學(xué)啦!更新節(jié)奏有點(diǎn)跟不上,這里做個檢討~

UU們開學(xué)感覺怎么樣呢?見到同學(xué)或者舍友有沒有很開心呢?又可以一起愉快地玩耍咯!

但是玩歸玩,學(xué)習(xí)還是正事,話不多說,開始今天的內(nèi)容。

在之前的內(nèi)容中,我們已經(jīng)把C語言的入門知識進(jìn)行了一個全面的講解,并介紹了一些實(shí)用的調(diào)試技巧,以及函數(shù)棧幀的創(chuàng)建和銷毀,可以說對于C語言已經(jīng)算是敲過開門磚了。

那么今天,我們就要開啟深入學(xué)習(xí)C語言的旅程啦!首先解決C語言進(jìn)階第一問:數(shù)據(jù)在內(nèi)存中是如何存儲的?

當(dāng)然,我們主要探討的是整型和浮點(diǎn)型這兩種類型。

數(shù)據(jù)類型

C語言中具以下幾種基本內(nèi)置類型:

這里說明一下:

  • C語言的基本內(nèi)置類型只的是C語言本身具有的類型,而庫函數(shù)本身是不屬于C語言的,是獨(dú)立于C語言之外的。
  • C語言是用來決定語言的語法形式的,而庫函數(shù)是編譯器的產(chǎn)商提供,當(dāng)然庫函數(shù)的使用是受C語言標(biāo)準(zhǔn)約束的(比如C語言標(biāo)準(zhǔn)規(guī)定了一些庫函數(shù)的函數(shù)名、參數(shù)類型、返回值類型和函數(shù)功能)。
  • 這樣做的好處是雖然不同編譯器實(shí)現(xiàn)函數(shù)的方式不一樣,但是對于我們來說,在不同的編譯器下使用函數(shù)的方式是一樣的。
  • 當(dāng)然在有一些編譯器中對一些庫函數(shù)的支持提供得不是很好,比如在VS編譯器下使用scanf函數(shù)就可能會報錯,需要使用scanf_s。

由于字符類型在存儲的時候是按照ASCII碼值存儲的,所以字符類型也屬于整型家族中的一員。

前面我們已經(jīng)學(xué)習(xí)了以上這么多的數(shù)據(jù)類型,并且了解了它們所占內(nèi)存空間的大小。

我們還要明白,我們?yōu)槭裁匆o數(shù)據(jù)分那么多的類型:

  1. 我們生活中出了的數(shù)除了整數(shù)就是小數(shù),所以為了更好地存儲這兩種類型,數(shù)據(jù)分為整型和浮點(diǎn)型兩大類
  2. 使用不同的類型時內(nèi)存開辟的空間大小是不一樣的(使用范圍也不一樣)。我們應(yīng)該根據(jù)數(shù)據(jù)的大小選擇合適的類型,如果選大了,則浪費(fèi)空間;選小了,則數(shù)據(jù)無法完整存儲。
  3. 不同類型決定了我們看待空間時應(yīng)該采用哪種視角。即對于內(nèi)存中不同空間的類型存和取的方式是不一樣的。

類型的基本歸類

整型家族

  • char
    unsigned char
    signed char
  • short
    unsigned short [int]
    signed short [int]
  • int
    unsigned int
    signed int
  • long
    unsigned long [int]
    signed long [int]
    -long long
    unsigned long long [int]
    signed long long [int]

注意:



如何理解有符號和無符號:

以char類型舉例:

這里也說明了不同類型決定了我們看待內(nèi)存中的值時視角也不同。

同時,我們也可以由此推算出一個類型中最大能放一個多大的數(shù)字。

還是以char類型舉例:

由此可以得出,有符號的char中可以存放的數(shù)的范圍是 -128 ~ 127。

相同道理:

無符號的char中可以存放的數(shù)的范圍是 0 ~ 255。

同理,我們可以得出short、int 、long等等類型的范圍。

浮點(diǎn)型

float
double

這兩種類型通常根據(jù)數(shù)據(jù)要求的精度來選擇:精度高選擇double類型(8個字節(jié)),精度低選擇float類型(4個字節(jié))。

一般我們更常選擇float類型,但是記住噢~3.14默認(rèn)是double類型哦!

構(gòu)造類型

除了內(nèi)置類型之外,還有構(gòu)造類型,即可以自己創(chuàng)造的類型。

數(shù)組類型
結(jié)構(gòu)體類型 struct
枚舉類型 enum
聯(lián)合類型 union

數(shù)組類型為什么也屬于構(gòu)造類型呢?

我們來看看數(shù)組的類型:


當(dāng)我們定義的數(shù)組元素的類型和個數(shù)不同時,數(shù)組的類型也不同,可以通過sizeof反映出來,所以我們也說數(shù)組屬于構(gòu)造類型。

指針類型

int *pi
char *pc
float *pf
void *pv

空類型

void表示空類型(即無類型)
常用于函數(shù)的返回類型、函數(shù)參數(shù)和指針類型

這里說void作為函數(shù)參數(shù)是什么情況呢?

正常我們在調(diào)用函數(shù)的時候,如果這個函數(shù)不需要傳參,則不寫參數(shù)。

但是如果是一個不需要傳參的函數(shù),而我們又給它傳參了,函數(shù)會怎樣呢?在有的編譯器中,會報錯,但是有的編譯器則會接受這種情況。

但是如果我們給參數(shù)加上一個void。編譯器就會報錯或者警告,告訴你不能傳參啦!

整型在內(nèi)存中的存儲

我們知道,一個變量創(chuàng)建之后是要在內(nèi)存中開辟空間的,那么這些變量在內(nèi)存中到底是怎么存儲的呢?

接下來我們就來看看~

首先看看整型在內(nèi)存中是如何存儲的。

我們知道,二進(jìn)制中有符號的整數(shù)有原碼、反碼、補(bǔ)碼三種表示方式。

這三種表示方式都有符號位和數(shù)值位兩部分。

  • 在符號位中,0表示“正”,1表示“負(fù)”。
  • 在數(shù)值位中,正數(shù)的原、反、補(bǔ)碼相同;負(fù)數(shù)的三種表示方法各不相同:
    原碼:直接將二進(jìn)制按照正負(fù)數(shù)的形式翻譯成二進(jìn)制。
    反碼:將原碼的符號位不變,其他位依次按位取反。
    補(bǔ)碼:反碼+1得到補(bǔ)碼。

我們知道對于整型來說,內(nèi)存中存放的是該數(shù)的補(bǔ)碼。

在計算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示和存儲。

但是存放的是補(bǔ)碼,而不是原碼或者反碼呢?

因?yàn)椋褂醚a(bǔ)碼可以將符號位和數(shù)值位作統(tǒng)一處理。

同時,加法和減法也可以統(tǒng)一處理(CPU只有加法器)。

因此,補(bǔ)碼與原碼相互轉(zhuǎn)換,其運(yùn)算過程是相同的,不需要額外的硬件電路。

比如,我們想計算1-1。但是因?yàn)镃UP只有加法運(yùn)算,所以我們可以把表達(dá)式寫成1+(-1)。


我們可以看到,用原碼計算,得不出正確的結(jié)果。

但是如果用補(bǔ)碼計算,情況就不一樣了。


從上圖的計算中,我們可以看出,使用補(bǔ)碼可以直接對符號位和數(shù)值位同一進(jìn)行處理。

這里有一個有意思的事情:

我們知道原碼、反碼和補(bǔ)碼都是怎么得到的,那么計算一下我們會發(fā)現(xiàn)用同樣的方法,我們也可以通過補(bǔ)碼得到原碼。


(不信你試著算一下!)

所以,由此我們可以看到用補(bǔ)碼來存儲的好處。

大小端字節(jié)序

定義


我們看到,a是一個十六進(jìn)制的數(shù),當(dāng)我們在內(nèi)存中查看它的存儲情況時,可以發(fā)現(xiàn),它的存放是從低地址開始放44 33 22 11。

對于它們在內(nèi)存中的存放順序,其實(shí)可以有很多種存放的方式。

但是如果大家都按照自己的想法來寫,則整個存儲就會亂套,而且如果我們不按照正常的順序存儲時,取出來要獲得原來的數(shù)就比較麻煩,所以我們最后決定只以下兩種存儲順序。


注意:這里的存儲順序是以字節(jié)為單位來討論的。因此,也稱字節(jié)序。

其中,上面的存儲順序稱為小端字節(jié)序;下面的存儲順序稱為大端字節(jié)序。

  • 小端字節(jié)序存儲
    把一個數(shù)的低位字節(jié)的內(nèi)容,存儲在內(nèi)存的低地址出,把這個數(shù)的高位字節(jié)的內(nèi)容,存儲在內(nèi)存的高地址處。
  • 大端字節(jié)序存儲
    把一個數(shù)的低位字節(jié)的內(nèi)容,存儲在內(nèi)存的高地址出,把這個數(shù)的高位字節(jié)的內(nèi)容,存儲在內(nèi)存的低地址處。

意義

那么,為什么在存儲時還要有大小端之分呢?

這是因?yàn)樵谟嬎銠C(jī)系統(tǒng)中,內(nèi)存空間的最小單元是一個字節(jié)。所以,如果我們存放的變量大小大于一個字節(jié)時,我們就不得考慮每個字節(jié)應(yīng)該以何種順序存放在內(nèi)存中了。

那么我們當(dāng)前的編譯器是采取大端存儲還是小端存儲呢?

別著急,回頭看看內(nèi)存中的值的順序,就能知道啦!

所以,我們當(dāng)前編譯器采用的是小端字節(jié)序。

百度曾經(jīng)出過一道筆試題,讓被試者設(shè)計一個程序來判斷當(dāng)前機(jī)器的字節(jié)序。

那么我們應(yīng)該如何做呢?

我們用1來進(jìn)行觀察。


所以,我們只需要拿出第一個字節(jié),看看里面存的是0還是1就知道了。

當(dāng)然,我們要實(shí)現(xiàn)的是查看一個機(jī)器字節(jié)序的功能,所以這里我們最好把程序封裝成一個函數(shù)。

浮點(diǎn)型在內(nèi)存中的存儲

看完了整數(shù)在內(nèi)存中是怎么存儲的,那么浮點(diǎn)型在內(nèi)存中又是怎么存儲的呢?

我們接下來就來看看。

首先我們常見的浮點(diǎn)數(shù)有:

小數(shù):3.1425926
科學(xué)計數(shù)法:1E10(1.0*1010

在浮點(diǎn)型中,我們有float和double兩種類型。

而這兩種類型的范圍,我們用float.h來定義。

如果我們想看整數(shù)的最大值(最小值),我們就用INT_MAX(INT_MIN);并在前面包含頭文件


然后我們就能看到int類型所能存放的最大值啦!


那么,浮點(diǎn)數(shù)所能存放的最大最小值是多少呢?

同理,我們可以用FLT_MAX(或者FLT_MIN、DBL_MAX等),引用頭文件,然后轉(zhuǎn)到定義。

就能得到他們的精度啦~

那么在內(nèi)存中浮點(diǎn)數(shù)的存儲和整數(shù)的存儲是一樣的嗎?

我們可以先通過一段代碼來進(jìn)行驗(yàn)證。


那么如果浮點(diǎn)型的存儲和整型不一樣,它又是怎么存儲的呢?

根據(jù)國際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會) 754,任意一個二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:

  • (-1)S * M * 2E
    (-1)s表示符號位,當(dāng)S=0,V為正數(shù);當(dāng)S=1,V為負(fù)數(shù)。
    M表示有效數(shù)字,1≤M<2。
    2E表示指數(shù)位。

我們以小數(shù)5.5來舉例。


同理,我們可以寫出9.0的表示形式:

我們會發(fā)現(xiàn),其實(shí)任何一個浮點(diǎn)數(shù)都可以寫成這種形式。

那么,只要我們把一個浮點(diǎn)數(shù)寫成(-1)S * M * 2E這種形式,那么只要我們存儲了S、M、E的信息,就能還原出浮點(diǎn)數(shù)的值了。

IEEE 754規(guī)定: 對于32位的浮點(diǎn)數(shù),最高的1位是符號位S,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

對于64位的浮點(diǎn)數(shù),最高的1位為符號位S,接著是11位的指數(shù)E,剩下的52位為有效數(shù)字M。

  • 此外,IEEE 754對有效數(shù)字M和指數(shù)E,還有一些特別規(guī)定。

因?yàn)?≤M<2 即M可以寫成1.XXXXXX 的形式,其中XXXXXX表示小數(shù)部分。

IEEE 754規(guī)定,在計算機(jī)內(nèi)部保存M時,默認(rèn)這個數(shù)的第一位總是1,因此這個1和它后面的小數(shù)點(diǎn)可以被舍去,只保存后面的XXXXXX部分。

比如:當(dāng)我們要保存1.01的時候,只需要保存01,等到讀取的時候,再把前面的1.加上去。

這樣,我們就節(jié)省了1位有效數(shù)字。

以32位浮點(diǎn)數(shù)(float)為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數(shù)字,這樣精度就得到了提高。

  • 那么對于指數(shù)E來說,它又是怎么存進(jìn)去的呢?

我們知道,對于指數(shù)E來說,它是可以去負(fù)數(shù)的,那么對于負(fù)數(shù)的E在存儲的時候,我們又應(yīng)該如何處理呢?

于是人們又想出了一個辦法,不如給這個E加上一個中間數(shù),讓E即使是最小的負(fù)數(shù),加上這個數(shù)之后也不會為負(fù)(等于0),那么就不會出現(xiàn)負(fù)數(shù)的情況了,只要我們?nèi)〕鰜淼臅r候再把這個中間數(shù)加上就行了。

這樣,我們就可以把E作為一個無符號整數(shù)了。

如果E為8位,那么它的取值范圍就是:0~255,那么它的中間數(shù)就是127。

對于11位的E,它的取值范圍是0~2047,它的中間數(shù)就是1023。

比如:210的E是10,所以保存成32位浮點(diǎn)數(shù)時,就保存成10+127=137,即10001001。

以5.5為例,我們可以在內(nèi)存中看到它的存儲。

并且我們可以發(fā)現(xiàn),對于浮點(diǎn)數(shù),它在內(nèi)存中的存儲也是有大小端的。

以上,我們就知道了浮點(diǎn)數(shù)在內(nèi)存中是怎么存的了。
那么它又是怎么取出來的呢?

按道理,我們是怎么放進(jìn)去的,就應(yīng)該是怎么取出來的。但是由于指數(shù)E比較特別,所以再取出來時,又有一些特別的規(guī)定。

在內(nèi)存中取出E時,我們有一下三種情況:

E不全為0或不全為1

這時,E是怎么存進(jìn)來的,我們就按照原路取出來。

即指數(shù)E的計算值減去127(或1023),得到真實(shí)值,再將有效數(shù)字M前加上第一位的1。

比如: 0.5的二進(jìn)制形式為0.1,由于規(guī)定正數(shù)部分必須為1,即將小數(shù)點(diǎn)右移1位,則為1.0*2^(-1)。

同理,反過來,我們可以通過這個二進(jìn)制序列得到0.5。

E全為0

當(dāng)E全為0的時候,說明浮點(diǎn)數(shù)的指數(shù)E等于-127,而2-127是一個非常非常小的數(shù),已經(jīng)十分接近于0了。

所以這時候,我們就不再按照原來的計算方式,而是把浮點(diǎn)數(shù)的指數(shù)E直接記為1-127(或者1-1023), 并且有效數(shù)字M不再加上第一位的1,而是還原為0.XXXXXX的小數(shù)。這樣做是為了表示±0,以及無窮接近于0的很小的數(shù)。

E全為1

當(dāng)E全為1時,則得到的是255,減去127得到的是128,而2128是一個非常大的數(shù)。所以這時,如果有效數(shù)字M全為0,則該數(shù)就表示±無窮大(正負(fù)取決于符號位S)

當(dāng)我們了解完以上浮點(diǎn)型在內(nèi)存中的存儲規(guī)則之后,我們就可以理解之前哪個代碼打印出來的值了。

今天的文章就到這里啦!~

你學(xué)廢了嗎?記得點(diǎn)贊收藏加關(guān)注,在評論區(qū)留下你的腳印~

關(guān)注我!一起精進(jìn)C語言!

今天的代碼都在這里咯!
https://gitee.com/fang-qiuhui/my-code/blob/4ab3bddffe0dc8e520fabbee219aa421f67d6c1b/blog_2021_8_30_data/blog_2021_8_30_data.cpp

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/119293.html

相關(guān)文章

  • C語言中還有這些類型,別再說你不知道了!把手帶你解鎖C語言自定義類型,讓你寫你所想。

    摘要:結(jié)構(gòu)體類型的特殊聲明在初階結(jié)構(gòu)體中,我們已經(jīng)將了結(jié)構(gòu)體類型是如何進(jìn)行聲明的,那么在這里,我們將講一些特殊的結(jié)構(gòu)體聲明不完全的聲明。所以我們應(yīng)該這樣寫通過指針來找到下一個同類型結(jié)構(gòu)體的寫法,我們就稱之為結(jié)構(gòu)體的自引用。 ...

    hizengzeng 評論0 收藏0
  • JavaScript - 收藏集 - 掘金

    摘要:插件開發(fā)前端掘金作者原文地址譯者插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實(shí)現(xiàn)文件分片斷點(diǎn)續(xù)傳。 Vue.js 插件開發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡單的方式。插....

    izhuhaodev 評論0 收藏0
  • C語言進(jìn)階學(xué)習(xí)】一、數(shù)據(jù)存儲 (深度剖析數(shù)據(jù)內(nèi)存存儲)

    摘要:的理解和區(qū)別代表有符號,整數(shù)在內(nèi)存中存儲的二進(jìn)制位的最高位為符號位,表示負(fù)數(shù),表示正數(shù)。那接下來我們來學(xué)習(xí)數(shù)據(jù)在所開辟的內(nèi)存空間時如何存儲的。請看下面例子為什么內(nèi)存中存儲的是補(bǔ)碼對于整數(shù)來說數(shù)據(jù)存放內(nèi)存中其實(shí)存放的是補(bǔ)碼。 ...

    AprilJ 評論0 收藏0
  • Java 總結(jié)

    摘要:中的詳解必修個多線程問題總結(jié)個多線程問題總結(jié)有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升開源的運(yùn)行原理從虛擬機(jī)工作流程看運(yùn)行原理。 自己實(shí)現(xiàn)集合框架 (三): 單鏈表的實(shí)現(xiàn) 自己實(shí)現(xiàn)集合框架 (三): 單鏈表的實(shí)現(xiàn) 基于 POI 封裝 ExcelUtil 精簡的 Excel 導(dǎo)入導(dǎo)出 由于 poi 本身只是針對于 ...

    caspar 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<