91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言重難點之內存對齊和位段的示例分析

發布時間:2021-05-11 15:05:22 來源:億速云 閱讀:153 作者:小新 欄目:開發技術

這篇文章主要介紹了C語言重難點之內存對齊和位段的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

C語言是什么

C語言是一門面向過程的、抽象化的通用程序設計語言,廣泛應用于底層開發,使用C語言可以以簡易的方式編譯、處理低級存儲器。

一:結構體內存對齊

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

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

性能原因:
數據結構(尤其是棧)應該盡可能的在自然邊界上對齊。原因在于,為了訪問未對齊內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需一次。

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

 舉個例子:對于有32根地址總線的計算機來說,每次讀取的單位是4個字節,假入定義了如下結構體:

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

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

(2)結構體對齊規則

  • 第一個成員在與結構體變量偏移量為0的地址處。(即結構體的首地址處,即對齊到0處)

  • 其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。

  • 結構體的總大小為最大對齊數(每個成員變量都有一個對齊數)的整數倍。

  • 如果嵌套了結構體,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。

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

(3)結構體對齊演示

以下面的構體為例

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

第一步:把結構體中每個成員變量的大小與編譯器的默認對齊數進行比較,取小的作為該成員的對齊數

C語言重難點之內存對齊和位段的示例分析

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

C語言重難點之內存對齊和位段的示例分析

故為16個字節

(4)練習

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

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

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

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

二:位段

(1)什么是位段

“節省空間”這四個字可以直截了當的點名位段的作用。

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

(2)位段怎么寫

位段的基本格式如下,和結構體十分相似,其內部的數據類型一般要求是一致的

C語言重難點之內存對齊和位段的示例分析

(3)位段結構體對齊怎么算

上述這個結構體所占空間大小為八個字節,在實際分配時,會一上來先分配四個字節,其中a,b,c占據2+5+10共17個比特位,剩余d需要30個比特位存儲但是不夠,所以再分配四個字節,拿出其中30個比特位存儲。可以看出相比之前暴力的直接16個字節,現在的8個字節大大的節省了空間。

再比如下面位段

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

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

 位段的跨平臺問題

  • int 位段被當成有符號數還是無符號數是不確定的。

  • 位段中最大位的數目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機

  • 器會出問題。

  • 位段中的成員在內存中從左向右分配,還是從右向左分配標準尚未定義。

  • 當一個結構包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是舍棄剩余的位還是利用,這是不確定的。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“C語言重難點之內存對齊和位段的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

韶山市| 衢州市| 宜宾市| 武邑县| 拜城县| 闻喜县| 将乐县| 修文县| 甘洛县| 利辛县| 印江| 镇巴县| 栖霞市| 平阴县| 彩票| 曲阜市| 永州市| 苏尼特右旗| 理塘县| 运城市| 遂川县| 巫山县| 伊春市| 海丰县| 乐昌市| 紫阳县| 巴中市| 辛集市| 青神县| 时尚| 湖口县| 广丰县| 卢龙县| 承德市| 彰化市| 潞城市| 白沙| 平安县| 柳州市| 察哈| 祥云县|