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

C語言重難點之內(nèi)存對齊和位段

 更新時間:2021年05月11日 11:11:42   作者:快樂江湖  
這篇文章主要介紹了C語言重難點之內(nèi)存對齊和位段,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一:結(jié)構(gòu)體內(nèi)存對齊

(1)為什么要存在內(nèi)存對齊

平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些平臺只能在某些地址處取得某些特定類型的數(shù)據(jù),否則拋出硬件異常。
比如,當(dāng)一個平臺要取一個整型數(shù)據(jù)時只能在地址為4的倍數(shù)的位置取得,那么這時就需要內(nèi)存對齊,否則無法訪問到該整型數(shù)據(jù)。

性能原因:
數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能的在自然邊界上對齊。原因在于,為了訪問未對齊內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問僅需一次。

核心思想就是:以空間換取時間

struct s1
{
char c1;
int i;
char c2;
}

由于c1占1個字節(jié),i占4個字節(jié),c2占1個字節(jié),所以計算機在讀取時候,會先讀取c1和i的3個字節(jié)(共四個字節(jié))、再讀取i的最后一個字節(jié)和c2。因此計算器不但需要進(jìn)行兩次內(nèi)存讀取,并且還需要對i的數(shù)據(jù)進(jìn)行拼接,無形中浪費了運行的時間。所以為了減少時間的浪費,就采用了內(nèi)存對齊的方式。

(2)結(jié)構(gòu)體對齊規(guī)則

  • 第一個成員在與結(jié)構(gòu)體變量偏移量為0的地址處。(即結(jié)構(gòu)體的首地址處,即對齊到0處)
  • 其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
  • 結(jié)構(gòu)體的總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍。
  • 如果嵌套了結(jié)構(gòu)體,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。

其中對齊數(shù)=編譯器默認(rèn)的一個對齊數(shù)與該成員大小的較小值。vs中默認(rèn)為8。Linux中默認(rèn)值為4。

(3)結(jié)構(gòu)體對齊演示

以下面的構(gòu)體為例

struct S
{
	double d;
	char c;
	int i;
};

第一步:把結(jié)構(gòu)體中每個成員變量的大小與編譯器的默認(rèn)對齊數(shù)進(jìn)行比較,取小的作為該成員的對齊數(shù)

在這里插入圖片描述

第二步:從0位開始,畫出這些成員的位置,注意對齊到自己的對齊數(shù)

在這里插入圖片描述

故為16個字節(jié)

(4)練習(xí)

//練習(xí)1
struct S1{
	char c1;
	int i;
	char c2;
};
printf("%d\n", printf(struct S1);//12

//練習(xí)2 
struct S2 {
    char c1;    
    char c2;    
    int i; 
 }; 
 printf("%d\n", sizeof(struct S2));//8

//練習(xí)3 
struct S3 {
    double d;    
    char c;    
    int i; 
}; 
printf("%d\n", sizeof(struct S3));//16

//練習(xí)4-結(jié)構(gòu)體嵌套問題 
struct S4 {
    char c1;    
    struct S3 s3;    
    double d; 
}; 
printf("%d\n", sizeof(struct S4));//32

二:位段

(1)什么是位段

“節(jié)省空間”這四個字可以直截了當(dāng)?shù)狞c名位段的作用。

在結(jié)構(gòu)體設(shè)計中,我們一般用int來存年齡這樣的數(shù)據(jù),但是年齡這個東西再大也不會達(dá)到幾百幾千,也就是它的范圍一般是1-100,反應(yīng)在整形數(shù)據(jù)的內(nèi)存上,使用的可能就是32個比特位中的個別幾個,也就說剩余的很多比特位就是根本不會用到的,而如果明知道這樣,還要不管三七二十一直接拋出一個整形,四個字節(jié),32個比特位存儲這么小的數(shù),未免顯的有點浪費了。所以正式鑒于此,位段就能合理的進(jìn)行內(nèi)存設(shè)計

(2)位段怎么寫

位段的基本格式如下,和結(jié)構(gòu)體十分相似,其內(nèi)部的數(shù)據(jù)類型一般要求是一致的

在這里插入圖片描述

(3)位段結(jié)構(gòu)體對齊怎么算

上述這個結(jié)構(gòu)體所占空間大小為八個字節(jié),在實際分配時,會一上來先分配四個字節(jié),其中a,b,c占據(jù)2+5+10共17個比特位,剩余d需要30個比特位存儲但是不夠,所以再分配四個字節(jié),拿出其中30個比特位存儲??梢钥闯鱿啾戎氨┝Φ闹苯?6個字節(jié),現(xiàn)在的8個字節(jié)大大的節(jié)省了空間。

再比如下面位段

struct A
{
	unsigned a : 19;
	unsigned b : 11;
	unsigned c : 4;
	unsigned d : 29;	
	char index;
};

其中a和b共占據(jù)4個字節(jié),c和d占據(jù)八個字節(jié),index對齊對齊1個字節(jié),最終就是16

 位段的跨平臺問題

  • int 位段被當(dāng)成有符號數(shù)還是無符號數(shù)是不確定的。
  • 位段中最大位的數(shù)目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機
  • 器會出問題。
  • 位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配標(biāo)準(zhǔn)尚未定義。
  • 當(dāng)一個結(jié)構(gòu)包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是舍棄剩余的位還是利用,這是不確定的。

到此這篇關(guān)于C語言重難點之內(nèi)存對齊和位段的文章就介紹到這了,更多相關(guān)C語言 內(nèi)存對齊和位段內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++11學(xué)習(xí)之右值引用和移動語義詳解

    C++11學(xué)習(xí)之右值引用和移動語義詳解

    c++11中引用了右值引用和移動語義,可以避免無謂的復(fù)制,提高了程序性能。這篇文章將通過一些示例和大家聊聊右值引用和移動語義的使用,感興趣的可以了解一下
    2023-02-02
  • 關(guān)于Qt?C++中connect的幾種寫法代碼示例

    關(guān)于Qt?C++中connect的幾種寫法代碼示例

    這篇文章介紹了Qt中connect函數(shù)的不同編寫方式,包括傳統(tǒng)的槽函數(shù)寫法、使用函數(shù)指針的寫法、Lambda表達(dá)式以及使用QOverload選擇重載信號的寫法,每種寫法都有其特點和適用場景,程序員應(yīng)根據(jù)具體需求選擇最合適的方式,需要的朋友可以參考下
    2024-11-11
  • C++變量,常量,數(shù)組和字符串詳解

    C++變量,常量,數(shù)組和字符串詳解

    這篇文章主要介紹了C++變量,常量,數(shù)組和字符串,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-10-10
  • C++利用easyx圖形庫實現(xiàn)創(chuàng)意天天酷跑小游戲

    C++利用easyx圖形庫實現(xiàn)創(chuàng)意天天酷跑小游戲

    這篇文章主要為大家詳細(xì)介紹了C++如何利用easyx圖形庫實現(xiàn)創(chuàng)意小游戲——天天酷跑,文中的示例代碼講解詳細(xì),快跟隨小編一起了解一下吧
    2023-03-03
  • C語言中if語句加大括號和不加大括號的區(qū)別介紹

    C語言中if語句加大括號和不加大括號的區(qū)別介紹

    這篇文章主要給大家介紹了關(guān)于C語言中if語句加大括號和不加大括號的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C語言 深入淺出講解指針的使用

    C語言 深入淺出講解指針的使用

    指針是C語言中一個非常重要的概念,也是C語言的特色之一。使用指針可以對復(fù)雜數(shù)據(jù)進(jìn)行處理,能對計算機的內(nèi)存分配進(jìn)行控制,在函數(shù)調(diào)用中使用指針還可以返回多個值
    2022-03-03
  • 詳解C++ thread用法總結(jié)

    詳解C++ thread用法總結(jié)

    這篇文章主要介紹了詳解C++ thread用法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • VS2019開發(fā)Linux C++程序的實現(xiàn)步驟

    VS2019開發(fā)Linux C++程序的實現(xiàn)步驟

    由于很多unix特有的函數(shù)無法在Windows上使用,而Vim又用的不太順手,突然想到最初用vs的時候有一個基于Linux的C++開發(fā)。本文就來介紹一下,感興趣的可以了解一下
    2021-07-07
  • C++利用jsoncpp庫實現(xiàn)寫入和讀取json文件

    C++利用jsoncpp庫實現(xiàn)寫入和讀取json文件

    JsonCpp 是一個C++庫,允許操作 JSON 值,包括序列化和反序列化到字符串和從字符串反序列化。本文主要介紹了如何利用jsoncpp庫實現(xiàn)寫入和讀取json文件,感興趣的可以了解一下
    2023-04-04
  • VC++ 中ListCtrl經(jīng)驗總結(jié)

    VC++ 中ListCtrl經(jīng)驗總結(jié)

    這篇文章主要介紹了VC++ 中ListCtrl經(jīng)驗總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06

最新評論

沿河| 琼结县| 镇坪县| 玛纳斯县| 荃湾区| 清涧县| 大关县| 红桥区| 乌拉特前旗| 阜平县| 福鼎市| 东乡族自治县| 商水县| 江安县| 墨玉县| 梁河县| 财经| 保康县| 钟山县| 安龙县| 即墨市| 博爱县| 宁国市| 大兴区| 巩留县| 越西县| 舒城县| 临洮县| 安福县| 夏河县| 藁城市| 丰城市| 天峨县| 祥云县| 子长县| 廉江市| 河间市| 邯郸县| 云南省| 自贡市| 昭平县|