struct a
; sizeof(struct a)=?
struct b
; sizeof(struct b)=?
struct c
; sizeof(struct c)=?
和老師交流時,老師給我出了幾道c/c++細節方面的問題,其中遇到了一道關於結構體在記憶體儲存的問題,老師先後變換了這幾種種情況,最後一種情況還是沒有回答上。回去考慮了下突然想起來怎麼回事。
對於結構體儲存,這涉及了計算機組成原理中我們學的位元組對齊,這也看出來計算機組成原理是何等的重要,所以對於作業系統,計算機組成原理這些課程一定要好好學習。
位元組對齊有助於加快計算機的取數速度,否則就得多花指令週期了。為此,編譯器缺省會對結構體進行處理(實際上其它地方的資料變數也是如此),讓寬度為2的基本資料型別(short等)都位於能被2整除的位址上,讓寬度為4的基本資料型別(int等)都位於能被4整除的位址上,以此類推。這樣,兩個數中間就可能需要加入填充位元組,所以整個結構體的sizeof值就增長了。
1) 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;
2) 結構體每個成員相對於結構體首位址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末乙個成員之後加上填充位元組(trailing padding)。
在預設情況下,vc規定各成員變數存放的起始位址相對於結構的起始位址的偏移量必須為該變數的型別所占用的位元組數的倍數。下面列出常用型別的對齊方式(vc6.0,32位系統)
型別 對齊方式(變數存放的起始位址相對於結構的起始位址的偏移量)
char 偏移量必須為sizeof(char)即1的倍數
int 偏移量必須為sizeof(int)即4的倍數
float 偏移量必須為sizeof(float)即4的倍數
double 偏移量必須為sizeof(double)即8的倍數
short 偏移量必須為sizeof(short)即2的倍數
各成員變數在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的位元組vc會自動填充。同時vc為了確保結構的大小為結構的位元組邊界數(即該結構中占用最大空間的型別所占用的位元組數)的倍數,所以在為最後乙個成員變數申請空間後,還會根據需要自動填充空缺的位元組。
當然,也可以人為的使用#pragma pack(n) /* n = 1, 2, 4, 8, 16 */ 來人為的設定對齊大小。
同時在stddef.h裡,提供了乙個巨集定義用來判斷結構體內某個成員的偏移量。
具體用法是:
size_t offsetof( structname, membername );
第乙個引數是結構體的名字,第二個引數是結構體成員的名字。該巨集返回結構體structname中成員membername的偏移量。偏移量是size_t型別的。
乙個最簡單的**示例
#include#includestruct a
;int main()
{ cout<
學會不同課程之間的聯通掌握,把握好他們之間的聯絡。
結構體儲存陣列
定義乙個結構體arr,裡面有三個元素,分別是指向陣列首元素位址的指標pbase,陣列的最大長度len和陣列當前的有效資料個數cnt。除此之外,還有多個對陣列進行多種操作的函式。include include include const int length 100 陣列最大長度 struct arr...
結構體儲存記憶體對齊
解析c語言結構體對齊 記憶體對齊問題 結構體對齊原因有很大部分是因為計算機掃瞄的記憶體單元個數,也就是資料匯流排的大小。原則1 資料成員對齊規則 結構 struct或聯合union 的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始 比如i...
結構體成員的儲存
剛開始學c語言只知道怎麼引用結構體成員變數,但卻很少關注結構體成員的儲存,儲存涉及到了記憶體對齊相關的知識,要能很準確的引用結構體成員變數也需要學習一下它的儲存。includetypedef struct node node,pnode int main pnode p nodetest print...