c語言中的位元組對齊

2021-07-08 21:52:41 字數 2522 閱讀 3667

一、什麼是位元組對齊?

計算機中的資料在儲存時並不是按順序儲存,因為在訪問特定的資料型別時通常從特定的記憶體位址開始,所以資料在儲存時特定的型別儲存時從特定的位址開始,比如我們所說的int型別的對齊數是4,意思是儲存這個int型別的變數的位址%4==0,這就是對齊數為4的意思。

二、為什麼要位元組對齊?

位元組對齊是的思想就是以空間換取時間。所以在儲存資料時採取位元組對齊的方式,可以讓cpu在訪存讀取資料時的效率大大提高。如果資料在儲存時是按照順序的方式來儲存的,比如說有些機器在訪存時每次都是從偶位址開始的,如果我們要訪問乙個int型的資料,我們採用位元組對齊的方式話,在32位的系統下我們通過一次訪存就可以讀出這個資料,如果沒有位元組對齊,那麼當這個整形數的起始位址是個奇位址時,我們要訪存兩次才可以完整的讀出這個資料,並且在讀出後還要通過拼接才能拿到這個整形數,相對而言我們採用位元組對齊的方式的效率高。

三、如何正確的理解資料儲存的位址?

在vc6.0下我們寫出這樣乙個程式

在記憶體中的應該是這樣的

可以看到char型的變數的起始位址是0018ff44,int型的變數的起始位址是0018ff40,可以看出這裡的儲存是使用的了位元組對齊的,char後面的三個位元組被浪費掉以保證我們的記憶體對齊。總結出下面幾條規則:

1、c語言中標準資料型別儲存的起始位址是它們長度的整數倍;

2、結構體中每個成員都要位元組對齊;

3、聯合中按它長度最大成員對齊;

4、陣列的首元素只要位元組對齊,剩餘元素肯定位元組對齊。

四、對於結構體資料大小的相關問題(以下例項是在vs下測試)

首先介紹偏移量

偏移量就是結構體成員相對於結構體的位址偏移,第乙個成員對於結構體的偏移量就是0。

所以對於結構體的大小計算有下面結果準則:

1、結構體變數中成員的偏移量必須是成員大小的整數倍

2、結構體大小必須是結構體成員中長度最大的成員的整數倍。

3、對於巢狀的結構體,其中巢狀的結構體的偏移量應該對齊其中長度最大的成員。

#include#includeint main()

; printf("%d\n", sizeof(struct a));

system("pause");

return 0;

}

執行結果:

a的偏移量是0,b的偏移量應該是sizeof(int)的整數倍,所以b的偏移量是從4開始的,所以結構體大小是8,結構體的大小必須是最大長度成員的整數倍,這裡也剛好滿足。

#include#includeint main()

; printf("%d\n", sizeof(struct a));

system("pause");

return 0;

}

結果是:

這個時候前面兩步的計算和上面的那個例子一樣,當存完c是這個時候的總偏移量是8,大小應該是9,但是9並不是最大成員的整數倍,所以往後還要在偏移三個位元組,因此得到結果12.

#include#includeint main()

; char c;

}; printf("%d\n", sizeof(struct a));

system("pause");

return 0;

}

結果是:

這裡有結構體的巢狀,這個時候存完int b之後的偏移是7,這個時候我們應該考慮的是結構體struct b中最大成員,可以看到double是它的最大成員,所以說這個時候的偏移應該是8的整數倍,剛好存它的其實偏移就是8,所以按照上面的規則,我們先計算struct b的大小是16,直接往後偏移16個位元組,完後在存char c,總偏移是24,大小是25,不是

8的整數倍(最大成員),所以往後偏移到31偏移處,大小為32。

************自己設定對齊數*****************

我們可以通過#pragma pack (n) /*指定按n位元組對齊*/

#pragma pack ()  /*恢復原有對齊數*/

注意是連用的!!!

這些例項是在vs下執行測試,在其他編譯器可能有所不同,具體情況要具體討論!

C語言中的位元組對齊

一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...

C語言中的位元組對齊

一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...

關於c語言中的位元組對齊padding問題

最近的工作中,發現有乙個很奇怪的問題,就是兩個結構體,裡面的字段的值完全是一樣的,但是用memcpy就是不返回0。大致是下面的 輸出是 aa bb bb cc 為什麼設的值都是一樣的,但是memcmp就是返回不一樣呢。memcpy還算是乙個比較常用的函式,特別是在c語言中比較乙個有較多字段的結構體,...