1. 程式人生 > >C語言中結構體內部成員的對齊

C語言中結構體內部成員的對齊

說明:

******不同的編譯器和處理器,其結構體內部的成員有不同的對齊方式。

******使用sizeof()運算子計算結構體的長度。

###結構體中每個成員相對於結構首地址的偏移量都是成員大小的整數倍,如果有需要編譯器會在成員之間加上填充字。

###結構體的總大小是結構體最寬基本型別成員大小的整數倍。如果需要編譯器會在最後一個成員之後加上填充字。

struct A
{
<span style="white-space:pre">	</span>unsigned short a;<span style="white-space:pre">	</span>//4bytes
	unsigned int b;<span style="white-space:pre">		</span>//4bytes
	unsigned char c;<span style="white-space:pre">	</span>//4bytes
}aa;
按結構體成員對齊,應該給c分配一個位元組的空間,但是還得按結構體的對齊方式,所以給c分配4個位元組。sizeof(aa)==12

結構體成員對齊,應當按結構體中最大基本資料型別來分配儲存空間,例如:當一個成員A分配的空間大於自己本身的大小時,若是下個成員B所需空間,A分配空間的剩下空間足以滿足儲存B的時候,那麼就不會給B分配了,但是,若不能滿足B的儲存的話,會給B按結構體最大資料型別來分配。

###計算結構體某個成員相對於結構體首地址的偏移量,通過巨集offsetof()可以獲得。

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//TYPE:結構體的型別
//MEMBER:結構體中某個成員
/*
 *offsetof(,)巨集解析:
 *(TYPE  *)0:將0強制轉換成指向結構體首地址的指標(結構體首地址為0地址)
 *((TYPE *)0)->MEMBER:結構體中某個變數
 * &((TYPE *)0)->MEMBER:取成員變數MEMBER(都是在0地址的基礎上增加的)的地址
 * (size_t) &((TYPE *)0)->MEMBER:將取到的地址強制轉換成size_t資料型別。
 */

結構體變數的初始化:

結構體:

struct A
{
	unsigned short b;
	unsigned int a;
	unsigned short c;
	unsigned short f;
	unsigned short g;
	unsigned short d;
	unsigned char e;
};

第一種初始化方法:

struct A aa={
	.b=2,
	.a=1,
	.c=3,
	.d=4,
	.e=5,
	.f=6,
	.g=7
	};	

第二種初始化方法:
struct A aa={1,2,3,4,5,6,7};

第三種初始化方法:
struct  A aa;
aa.b=2;
aa.a=1;
aa.c=3;
aa.d=4;
aa.e=5;
aa.f=6;
aa.g=7;