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

C語言大小端字節(jié)序存儲模式深入解讀

 更新時間:2022年09月22日 08:52:05   作者:碳基肥宅  
我們知道,當(dāng)編譯器執(zhí)行 “創(chuàng)建變量” 這一代碼時,會在內(nèi)存中開辟空間相應(yīng)的空間來存儲變量值。而對于整型變量而言,變量值又是以二進(jìn)制補碼的形式存放的

前言

本文以C語言實現(xiàn),主要通過例題+說明的模式講解存儲模式:大小端字節(jié)序。

對于正整數(shù)而言,它的補碼 = 原碼 = 反碼;

對于負(fù)整數(shù)而言,它的補碼 = 原碼按位取反(就是反碼) + 1;

例如,當(dāng)語句int a = 500被執(zhí)行時,內(nèi)存中會開辟 4字節(jié)(即32bit)的空間存儲整數(shù)20的二進(jìn)制補碼(00000000 00000000 0000000111110100)。同時,我們也知道,內(nèi)存中的每一個存儲單元的大小為 1字節(jié)(8bit)。

那么此時問題來了:int a = 500所占的總空間是4字節(jié),然而每一個內(nèi)存單元只存的下1字節(jié)的數(shù)據(jù),換句話說,每一個整型數(shù)據(jù)需要4個存儲單元才能存的下——那么,這4個存儲單元在內(nèi)存中到底是如何分布的呢?

是像數(shù)組一樣,用來存儲數(shù)據(jù)的4個內(nèi)存單元彼此之間連續(xù)開辟,還是物理空間上其實并不連續(xù)、只是解析數(shù)據(jù)時把4個單元中的數(shù)據(jù)“拼”到一起,還原出連續(xù)的整型數(shù)呢?

每一個字節(jié)的數(shù)據(jù),如何“被安排”存儲空間?

這個問題,本質(zhì)上是數(shù)據(jù)在內(nèi)存中的存儲模式問題。這就關(guān)系到我們今天要介紹的重點:大端數(shù)據(jù)存儲模式或小端數(shù)據(jù)存儲模式(即大端字節(jié)序與小端字節(jié)序)。

我們打開編譯器vs2019的內(nèi)存監(jiān)視,可以從監(jiān)視窗口看到數(shù)值在內(nèi)存中的存儲情況(顯示為16進(jìn)制)。

注意:32位下,

20的16進(jìn)制補碼為:00 00 00 14

-10的十六進(jìn)制補碼為:ff ff ff f6

兩個16進(jìn)制位恰好是一個字節(jié)8bit。我們將視圖調(diào)整為每行顯示4個字節(jié)(即一個int,這樣看得更清晰),于是可以發(fā)現(xiàn),在內(nèi)存中數(shù)據(jù)似乎是“倒著存”的。00 00 00 14在內(nèi)存中的存儲顯示為了14 00 00 00.

事實上,這并不叫做“倒著存”,這正是我們上面提到過的:小端字節(jié)序的存儲模式。在閱讀完本文后,我們就能明白。

一、大小端介紹

當(dāng)一個數(shù)值的大小超過 1字節(jié) ,那么它要存到內(nèi)存中,字節(jié)與字節(jié)之間就有存儲順序的問題。這個順序稱之為字節(jié)序。

以int類型為例。

理論上來說,即使存儲一個int型數(shù)據(jù)的4個存儲單元不連續(xù),甚至天南海北,只要最終解析時能還原成一個正常的數(shù)即可。但是這么做屬實沒有必要:計算機(jī)中存儲肯定是采用最便捷的存儲方式,那就是連續(xù)存儲,一個整型的4個字節(jié)空間挨在一塊兒。

這時要考慮的問題便是,這四個挨在一塊的存儲空間,是由低地址向高地址存儲,還是由高地址向低地址存儲?

1. 大端字節(jié)序與小端字節(jié)序的概念

小端字節(jié)序:把一個數(shù)值的低位字節(jié)內(nèi)容存放在低地址處;高位字節(jié)內(nèi)容存放在高地址處。(低位存低地址,高位存高地址)。

大端字節(jié)序:把一個數(shù)值的低位字節(jié)內(nèi)容存放在高地址處;高位字節(jié)內(nèi)容存放在低地址處。(低位存高地址,高位存低地址)。

例如,要存儲一個十六進(jìn)制數(shù) 0x11223344。該數(shù)中右端是低數(shù)位,左端是高數(shù)位(類比十進(jìn)制數(shù),十進(jìn)制數(shù)10里面0是個位更低,1是十位更高)。

小端存儲情況如下:

小端存儲模式示意

小端存儲模式下,若取出該int型數(shù)據(jù)的首地址內(nèi)容會發(fā)現(xiàn),存的其實是0x44。

而大端存儲情況如下:

大端存儲模式示意

以上就是對大小端存儲模式的理解。

至于實際中如何存儲的,還取決于具體編譯器的選擇?,F(xiàn)在大部分的編譯器選擇的是小端存儲模式,也就是我們上面看到的“倒著存”。

這時再參照引言中的例子,應(yīng)該能對這兩種存儲模式有一個較好的理解了。

2. 為什么會有大小端之分?

這是因為在計算機(jī)系統(tǒng)中,我們以字節(jié)為單位,每個地址單元都對應(yīng)著一個字節(jié),一個字節(jié)為8 bit 。但是在 C 語言中,除了 8 bit 的 char 之外,還有 16 bit 的 short 型,32 bit 的 long 型(要看具體的編譯器);另外,對于位數(shù)大于 8 位的處理器,例如 16 位或者 32位的處理器,由于寄存器寬度大于一個字節(jié),那么必然存在著一個如何將多個字節(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 處理器還可以由硬件來選擇是大端模式還是小端模式。

3.一道和字節(jié)序相關(guān)的例題

題干

在小端機(jī)器中,下面代碼輸出的結(jié)果是:

#include <stdio.h>
int main()
{
	int a = 0x11223344;
    char *pc = (char*)&a;
    *pc = 0;
    printf("%x\n", a);
    return 0;
}

思路

本題中的數(shù)值與我們上面討論的數(shù)值一樣,應(yīng)該不難理解:

1. char*類型的指針變量pc指向的只能指向char類型的空間。如果是非char類型的空間,則必須將該空間的地址強轉(zhuǎn)為char*類型。

2. char *pc = (char*)&a; pc實際指向的是整形變量a的空間,即指針pc里放的是0x00405090,指向的值即0x44。

3. *pc=0,關(guān)鍵一步:究竟是將哪個存儲單元中的值置零了?由首個單元中存儲的內(nèi)容可知,將0x44位置中內(nèi)容改為了0。修改完成之后,a中內(nèi)容為:0x11223300 (數(shù)值書寫肯定是高數(shù)位在左,低數(shù)位在右)

二、如何設(shè)計一個小程序判斷當(dāng)前機(jī)器的字節(jié)序

百度2015年系統(tǒng)工程師筆試題

題干

請簡述大端字節(jié)序和小端字節(jié)序的概念,設(shè)計一個小程序來判斷當(dāng)前機(jī)器的字節(jié)序。( 10 分)

解題

概念部分同上,在此不再贅述。

代碼部分:

1. 要檢測某一機(jī)器是大端還是小端其實并不難,我們可以直接用int類型的1來檢測。

2. 1在內(nèi)存中的二進(jìn)制補碼為:00000000000000000000000000000001

也就是說,我們只需要把首個內(nèi)存單元的值取出來看看是0還是1,就能判斷它是大端還是小端。

因為如果是大端,則“高數(shù)位存在低地址”,我們?nèi)〕鲎畹偷刂返闹?,?yīng)當(dāng)是最高數(shù)位上的數(shù)00000000;而若是小端,則“低數(shù)位存在低地址”,依然取出最低地址的值,應(yīng)當(dāng)是00000001

依照該思路,有以下代碼:

#include <stdio.h>
int check_sys()
{
     int i = 1;
     return (*(char *)&i);
}
int main()
{
     int ret = check_sys();
     if(ret == 1)
     {
         printf("小端\n");
     }
     else
     {
         printf("大端\n");
     }
    return 0; 
}

當(dāng)然,也可以用共用體來實現(xiàn)檢查,這是更為便捷的一種方式:

int check_sys()
{
     union
     {
         int i;
         char c;
     }un;
     un.i = 1;
    return un.c; 
}

到此這篇關(guān)于C語言大小端字節(jié)序存儲模式深入解讀的文章就介紹到這了,更多相關(guān)C語言大小端字節(jié)序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在C/C++項目中合理使用宏詳解

    在C/C++項目中合理使用宏詳解

    這篇文章主要介紹了在C/C++項目中合理使用宏詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 結(jié)構(gòu)體對齊的規(guī)則詳解及C++代碼驗證

    結(jié)構(gòu)體對齊的規(guī)則詳解及C++代碼驗證

    在c語言的結(jié)構(gòu)體里面一般會按照某種規(guī)則去進(jìn)行字節(jié)對齊。本文就來介紹一下如何實現(xiàn),具有一定的參考價值,感興趣的可以了解下
    2021-08-08
  • C++實現(xiàn)LeetCode(81.在旋轉(zhuǎn)有序數(shù)組中搜索之二)

    C++實現(xiàn)LeetCode(81.在旋轉(zhuǎn)有序數(shù)組中搜索之二)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(81.在旋轉(zhuǎn)有序數(shù)組中搜索之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 簡單分析C語言中指針數(shù)組與數(shù)組指針的區(qū)別

    簡單分析C語言中指針數(shù)組與數(shù)組指針的區(qū)別

    這篇文章主要介紹了C語言中指針數(shù)組與數(shù)組指針的區(qū)別,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • C++ 花括號{}初始化小結(jié)

    C++ 花括號{}初始化小結(jié)

    在C++11及以后的版本中,花括號{}語法在不同語境下有不同的用法,本文就詳細(xì)的介紹C++ 花括號{}初始化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • c++與c中的數(shù)組初始化默認(rèn)值如何為0

    c++與c中的數(shù)組初始化默認(rèn)值如何為0

    這篇文章主要介紹了c++與c中的數(shù)組初始化默認(rèn)值如何為0問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語言的數(shù)組指針與函數(shù)指針詳解

    C語言的數(shù)組指針與函數(shù)指針詳解

    這篇文章主要為大家詳細(xì)介紹了C語言的數(shù)組指針與函數(shù)指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件操作的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • C語言怎么獲得進(jìn)程的PE文件信息

    C語言怎么獲得進(jìn)程的PE文件信息

    這篇文章主要介紹了C語言怎么獲得進(jìn)程的PE文件信息的相關(guān)代碼,需要的朋友可以參考下
    2016-01-01
  • c語言結(jié)構(gòu)體字節(jié)對齊的實現(xiàn)方法

    c語言結(jié)構(gòu)體字節(jié)對齊的實現(xiàn)方法

    在c語言的結(jié)構(gòu)體里面一般會按照某種規(guī)則去進(jìn)行字節(jié)對齊。本文就來介紹一下如何實現(xiàn),具有一定的參考價值,感興趣的可以了解下
    2021-07-07

最新評論

淮安市| 大石桥市| 静海县| 漳平市| 庆安县| 拉孜县| 神农架林区| 锡林浩特市| 海安县| 兴文县| 呼玛县| 泰和县| 永川市| 牡丹江市| 福泉市| 磐石市| 浦城县| 安仁县| 汉川市| 弥渡县| 呼图壁县| 泰顺县| 瑞金市| 九龙坡区| 眉山市| 安丘市| 安平县| 岚皋县| 资兴市| 武陟县| 都昌县| 通渭县| 大荔县| 丰顺县| 东丰县| 昭通市| 罗定市| 花莲县| 龙泉市| 胶南市| 博野县|