最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言中數(shù)據(jù)如何存儲進內(nèi)存揭秘

 更新時間:2022年08月18日 11:38:06   作者:Zoroxs  
使用編程語言進行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么

內(nèi)存簡單介紹

大家肯定經(jīng)常聽說內(nèi)存這個詞,內(nèi)存到底是什么呢? 在計算機中,進程都要加載進內(nèi)存中,也是我們各種數(shù)據(jù)的流通途徑,C語言中,大家肯定都知道指針變量,指針變量中保存的就是內(nèi)存的地址,那么,什么是內(nèi)存的地址呢?

內(nèi)存的單位是字節(jié)

對于32位的機器,有32根地址線,每根地址線在尋址時,產(chǎn)生的高低電壓分別為0/1,那么32根地址線產(chǎn)生的地址就會是

00000000000000000000000000000000

00000000000000000000000000000001

00000000000000000000000000000010

11111111111111111111111111111111

這里就有2^32次方個地址

大家應(yīng)該知道,還有64位的機器,64根地址線又有多少個地址呢,大家可以計算一下

在32位的機器上,地址是32個0或者1組成二進制序列,那地址就得用4個字節(jié)的空間來存儲,

所以一個指針變量的大小就應(yīng)該是4個字節(jié)。 那如果在64位機器上,有64個地址線,那一個指針變量的大小是8個字節(jié),才能存放一個地址。

這串編號就是內(nèi)存單元的地址,就像酒店的房間號一樣,對應(yīng)著內(nèi)存中的一個字節(jié)大小的房間

我們在vs中來看一下

這里是以十六進制的方式展示的,大家也知道,32個數(shù)字看起來太長了。

整數(shù)與字符在內(nèi)存中的存儲

關(guān)于c語言中的數(shù)據(jù)類型,大家在寫了這么多代碼后肯定也很清楚了,C語言中有整型、浮點型、字符型、等等

我們來研究一下整數(shù)在內(nèi)存中是如何存儲的

大家都知道,定義變量,會在內(nèi)存中開辟空間來存儲

int a = 20;

int類型在vs中占據(jù)4個字節(jié)的空間,那么如何存儲呢?

這就涉及到原碼反碼補碼的概念

  • 計算機中的整數(shù)有三種2進制表示方法,即原碼、反碼和補碼。
  • 三種表示方法均有符號位和數(shù)值位兩部分,符號位都是用0表示“正”,用1表示“負”,剩下數(shù)值位
  • 正數(shù)的原、反、補碼都相同。
  • 負整數(shù)的三種表示方法各不相同。

原碼:

直接將數(shù)值按照正負數(shù)的形式翻譯成二進制就可以得到原碼

反碼:

將原碼的符號位不變,其他位依次按位取反就可以得到反碼

補碼:

反碼+1就得到補碼。

對于整型變量來說,內(nèi)存中存放的其實是補碼

使用補碼,可以將符號位和數(shù)值域統(tǒng)一處理,加法和減法也可以同一處理,因為CPU只有加法器

eg:

int a = 20;
//原碼 : 直接寫二進制    00000000000000000000000000010100
//反碼--補碼  -- 正數(shù)的原反補相同
int  b =  -5;
//原碼:   10000000000000000000000000000101
//反碼:符號位不變,按位取反
//        11111111111111111111111111111010
//補碼:反碼+1
//        11111111111111111111111111111011  --   -5的補碼

上邊可以看見-5的補碼是11111111111111111111111111111011 ,我們?nèi)绾未_認(rèn)呢?

轉(zhuǎn)換成16進制為fffffffb

大家可以看到確實是使用補碼存儲的,但是為什么是倒著存儲的,后邊再來說,這是由于大小端的問題

給大家舉幾個例子,不知道存儲無法分析出結(jié)果代碼

//1.
#include <stdio.h>
int main()
{
  char a = -128;
  printf("%u\n",a);
  //-128 原碼:  10000000 00000000 00000000 10000000
  //-128 反碼:  11111111 11111111 11111111 01111111
  //-128 補碼:  11111111 11111111 11111111 10000000
  //存在a里面的,因為只有一個字節(jié)   10000000
  //所以會當(dāng)做無符號整數(shù)打印 --整形提升
  //提升為  11111111111111111111111110000000
  //所以結(jié)果是一個很大的整數(shù),大家可以嘗試一下
  return 0;
}

#include <stdio.h>
int main()
{
  char a = 128;
  //128的原碼反碼補碼 : 00000000000000000000000010000000
  //存在a里的:10000000
  //整形提升 :11111111111111111111111110000000
  //所以結(jié)果還是那個很大的整數(shù)
  printf("%u\n",a);
  return 0;

例子就簡單給大家舉到這里,大家一定要記住整數(shù)在內(nèi)存中是以補碼的形式存儲的

字符存儲的是ASCII碼,所以和整數(shù)同

浮點數(shù)在內(nèi)存中的存儲

我們來看一下浮點數(shù)在內(nèi)存中的存儲

拋磚引玉:

#include <stdio.h>
int main()
{
    int n = 9;
    float *pFloat = (float *)&n;
    printf("n的值為:%d\n",n);
    printf("*pFloat的值為:%f\n",*pFloat);
    *pFloat = 9.0;
    printf("num的值為:%d\n",n);
    printf("*pFloat的值為:%f\n",*pFloat);
    return 0;
}

上面代碼的打印結(jié)果到底是什么呢?

是不是非常出乎大家的意料呢,這里就可以看出,浮點數(shù)的存儲肯定和整數(shù)是不同的。那浮點數(shù)到底咋存的呢?

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

  • (-1)^S * M * 2^E
  • (-1)^S表示符號位,當(dāng)S=0,V為正數(shù);當(dāng)S=1,V為負數(shù)。
  • M表示有效數(shù)字,大于等于1,小于2。
  • 2^E表示指數(shù)位。

看得很迷糊,直接上例子

v = 5.5

= 101.1 --二進制表示

= 1.011 * 2 ^2 – 科學(xué)記數(shù)法表示

因為是正數(shù) s = 0

m = 1.011

e = 2

IEEE 754規(guī)定:

對于32位的浮點數(shù),最高的1位是符號位s,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

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

1=<M <2 ,所以M可以寫成1.xxxxx 所以可以舍去1 ,只存儲xxxxxx

IEEE 754規(guī)定,在計算機內(nèi)部保存M時,默認(rèn)這個數(shù)的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的時候,只保存01,等到讀取的時候,再把第一位的1加上去。這樣做的目的,是節(jié)省1位有效數(shù)字。以32位浮點數(shù)為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數(shù)字

對于指數(shù)E,E是一個無符號整數(shù),但是科學(xué)記數(shù)法指數(shù)是可以出現(xiàn)負數(shù)的,所以

IEEE 754規(guī)定了偏移量,如果E為8位,則加上127 ,如果E為11位,則加上1023

我們舉個例子

float f = 8.5f;
//二進制 : 1001.1
//科學(xué)計數(shù)法表示: 1.0011*2^3
//S = 0 M = 1.0011  E = 3
//存儲進去的應(yīng)該是:
    0 10000010 00110000000000000000000
//我們可以驗證一下
        轉(zhuǎn)換成16進制
 0100 0001 0001 1000 0000 0000 0000 0000
//41 18 00 00

我們來看一下代碼

和我們想的一樣

我們再來舉一個負數(shù)的例子

float t = -3.5f;
//二進制: 11.1
//科學(xué)記數(shù)法: 1.11*2^1
//S = 1 M = 1.11 E = 1
//存儲:
1  10000000 11000000000000000000000
//轉(zhuǎn)換成16進制
1100 0000 0011 0000 0000 0000 0000 0000
c0 60 00 00

那我們從內(nèi)存中讀取出來的二進制位如何解析成浮點數(shù)呢

關(guān)于E,有三種情況

E不全為0或不全為1

這時,浮點數(shù)就采用下面的規(guī)則表示,即指數(shù)E的計算值減去127(或1023),得到真實值,再將有效數(shù)字M前加上第一位的1

2.E全為0

這時,浮點數(shù)的指數(shù)E等于1-127(或者1-1023)即為真實值,

有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0,以及接近于 0的很小的數(shù)字。

3.E全為1

這時,如果有效數(shù)字M全為0,表示±無窮大(正負取決于符號位s);

我們來分析一下最開始的題目

浮點數(shù)和整數(shù)的存儲就介紹到這里了,有哪里不清楚的朋友可以私信我

大小端存儲模式及簡介

上邊有一個懸念,為什么是倒序存儲的

那什么是大端小端呢?

大端(存儲)模式: 數(shù)據(jù)的低位存儲在內(nèi)存的高地址中,數(shù)據(jù)的高位存儲在內(nèi)存的低地址中

小端(存儲)模式: 數(shù)據(jù)的低位存儲在內(nèi)存的低地址中,數(shù)據(jù)的高位存儲在內(nèi)存的高地址中

那為什么會有大小端呢?

內(nèi)存中以字節(jié)為單位,但是比如int 是4個字節(jié),那如何安排這個4個字節(jié)呢?就導(dǎo)致了大小端存儲模式

例如:一個 16bit 的 short 型 x ,在內(nèi)存中的地址為 0x0010 , x 的值為 0x1122 ,那么 0x11 為高字節(jié), 0x22 為低字節(jié)。對于大端模式,就將 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,剛好相反。我們常用的 X86 結(jié)構(gòu)是小端模式,而 KEIL C51 則 為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式 還是小端模式。

那我們?nèi)绾螠y試當(dāng)前電腦是哪種存儲模式呢?

int main(void)
{
	int a = 0x11223344;
	return 0;
}

我們調(diào)試打開內(nèi)存看一下

很明顯,數(shù)據(jù)的低位存儲在內(nèi)存低地址中,所以為小端存儲模式。

我們能不能寫一個程序,直接告訴我們大小端呢?

我們來分析一下

我們來看一下代碼

int decide_byte_orde()
{
    int i = 1;
    return *(char *)&i;
}

我們來測試一下

總結(jié)

深入理解數(shù)據(jù)的存儲是非常有必要的,我們之后碰到很多問題都會豁然開朗,大家一定要好好研究一下

到此這篇關(guān)于C語言中數(shù)據(jù)如何存儲揭秘的文章就介紹到這了,更多相關(guān)C語言數(shù)據(jù)存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)讀取圖片長度和寬度

    C++實現(xiàn)讀取圖片長度和寬度

    這篇文章主要介紹了C++實現(xiàn)讀取圖片長度和寬度,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04
  • C/C++獲取Windows平臺CPU占用率的方法

    C/C++獲取Windows平臺CPU占用率的方法

    最近在做系統(tǒng)信息相關(guān)的接口,為了實現(xiàn)跨平臺,故在linux和Windows平臺獲取占用率信息,文章主要介紹Windows下的方法,文中給出了參考代碼,需要的朋友可以參考下
    2023-12-12
  • c++11中regex正則表達式示例簡述

    c++11中regex正則表達式示例簡述

    這篇文章主要給大家介紹了關(guān)于c++11中regex正則表達式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用c++11具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • C++的內(nèi)聯(lián)函數(shù)你了解嗎

    C++的內(nèi)聯(lián)函數(shù)你了解嗎

    這篇文章主要為大家詳細介紹了C++的內(nèi)聯(lián)函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C語言修煉之路數(shù)據(jù)類型悟正法 解析存儲定風(fēng)魔下篇

    C語言修煉之路數(shù)據(jù)類型悟正法 解析存儲定風(fēng)魔下篇

    使用編程語言進行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么
    2022-02-02
  • 深入學(xué)習(xí)C語言中的函數(shù)指針和左右法則

    深入學(xué)習(xí)C語言中的函數(shù)指針和左右法則

    這篇文章主要介紹了深入學(xué)習(xí)C語言中的函數(shù)指針和左右法則,左右法則是一種常用的C指針聲明,需要的朋友可以參考下
    2015-08-08
  • C語言的動態(tài)內(nèi)存分配及動態(tài)內(nèi)存分配函數(shù)詳解

    C語言的動態(tài)內(nèi)存分配及動態(tài)內(nèi)存分配函數(shù)詳解

    這篇文章主要為大家詳細介紹了C語言的動態(tài)內(nèi)存分配及動態(tài)內(nèi)存分配函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++代碼規(guī)范之命名規(guī)則

    C++代碼規(guī)范之命名規(guī)則

    以下是對C++中的命名規(guī)則進行了詳細的分析介紹,需要的朋友可以參考下
    2013-07-07
  • C語言實現(xiàn)掃雷游戲詳解

    C語言實現(xiàn)掃雷游戲詳解

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 在C++中如何阻止類被繼承詳解

    在C++中如何阻止類被繼承詳解

    這篇文章主要介紹了在C++中如何阻止類被繼承,對于C++初學(xué)者而言可以通過本文實例更好的理解類的原理及運用,需要的朋友可以參考下
    2021-09-09

最新評論

开原市| 东乌| 赣州市| 包头市| 揭西县| 东海县| 茂名市| 吴川市| 团风县| 丹江口市| 甘孜县| 富平县| 夹江县| 乌鲁木齐县| 延寿县| 法库县| 石嘴山市| 白玉县| 旌德县| 德令哈市| 息烽县| 江山市| 揭东县| 湾仔区| 万全县| 屏山县| 聂拉木县| 南澳县| 嫩江县| 长沙市| 昌宁县| 玉屏| 沙河市| 白城市| 昌乐县| 青川县| 台湾省| 嵊泗县| 镶黄旗| 晋中市| 左云县|