欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言重難點(diǎn)之內(nèi)存對(duì)齊和位段

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

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

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

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

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

核心思想就是:以空間換取時(shí)間

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

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

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

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

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

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

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

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

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

在這里插入圖片描述

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

在這里插入圖片描述

故為16個(gè)字節(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)體嵌套問(wèn)題 
struct S4 {
    char c1;    
    struct S3 s3;    
    double d; 
}; 
printf("%d\n", sizeof(struct S4));//32

二:位段

(1)什么是位段

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

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

(2)位段怎么寫(xiě)

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

在這里插入圖片描述

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

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

再比如下面位段

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

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

 位段的跨平臺(tái)問(wèn)題

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

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

相關(guān)文章

  • C++?Boost?CircularBuffer算法超詳細(xì)精講

    C++?Boost?CircularBuffer算法超詳細(xì)精講

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)
    2022-11-11
  • Visual?Studio?2022?安裝低版本?.Net?Framework的圖文教程

    Visual?Studio?2022?安裝低版本?.Net?Framework的圖文教程

    這篇文章主要介紹了Visual?Studio?2022?如何安裝低版本的?.Net?Framework,首先打開(kāi)?Visual?Studio?Installer?可以看到vs2022?只支持安裝4.6及以上的版本,那么該如何安裝4.6以下的版本,下面將詳細(xì)介紹,需要的朋友可以參考下
    2022-09-09
  • C語(yǔ)言深入探究自定義類(lèi)型之結(jié)構(gòu)體與枚舉及聯(lián)合

    C語(yǔ)言深入探究自定義類(lèi)型之結(jié)構(gòu)體與枚舉及聯(lián)合

    今天我們來(lái)學(xué)習(xí)一下自定義類(lèi)型,自定義類(lèi)型包括結(jié)構(gòu)體、枚舉、聯(lián)合體,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考
    2022-05-05
  • C++中形參和實(shí)參的區(qū)別及說(shuō)明

    C++中形參和實(shí)參的區(qū)別及說(shuō)明

    這篇文章主要介紹了C++中形參和實(shí)參的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C/C++語(yǔ)言八大排序算法之桶排序全過(guò)程示例詳解

    C/C++語(yǔ)言八大排序算法之桶排序全過(guò)程示例詳解

    這篇文章主要為大家介紹了C/C++語(yǔ)言八大排序算法之桶排序算法過(guò)程的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    這些宏定義在stdarg.h中,所以用到可變參數(shù)的程序應(yīng)該包含這個(gè)頭文件.下面我們寫(xiě)一個(gè)簡(jiǎn)單的可變參數(shù)的函數(shù),該函數(shù)至少有一個(gè)整數(shù)參數(shù),第二個(gè)參數(shù)也是整數(shù),是可選的.函數(shù)只是打印這兩個(gè)參數(shù)的值
    2013-09-09
  • 用C語(yǔ)言舉例講解數(shù)據(jù)結(jié)構(gòu)中的算法復(fù)雜度結(jié)與順序表

    用C語(yǔ)言舉例講解數(shù)據(jù)結(jié)構(gòu)中的算法復(fù)雜度結(jié)與順序表

    這篇文章主要介紹了講解數(shù)據(jù)結(jié)構(gòu)中的算法復(fù)雜度結(jié)與順序表的C語(yǔ)言版示例,包括對(duì)時(shí)間復(fù)雜度和空間復(fù)雜度等概念的簡(jiǎn)單講解,需要的朋友可以參考下
    2016-02-02
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C語(yǔ)言實(shí)現(xiàn)數(shù)組元素排序方法詳解

    C語(yǔ)言實(shí)現(xiàn)數(shù)組元素排序方法詳解

    這篇文章主要為大家介紹了C語(yǔ)言算法練習(xí)中數(shù)組元素排序的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下
    2023-02-02
  • C語(yǔ)言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實(shí)現(xiàn)

    C語(yǔ)言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實(shí)現(xiàn)

    堆就是用數(shù)組實(shí)現(xiàn)的二叉樹(shù),所以它沒(méi)有使用父指針或者子指針。堆根據(jù)“堆屬性”來(lái)排序,“堆屬性”決定了樹(shù)中節(jié)點(diǎn)的位置
    2021-11-11

最新評(píng)論