C 語言結構體 struct 及內存對齊

struct 結構體

對於複雜的數據類型(例如學生、汽車等),C 語言容許咱們將多種數據封裝到一塊兒,構成新類型。web

跟面嚮對象語言中的對象相比,結構體只能包含成員變量,不支持操做。svg

#include <stdio.h>
#include <string.h>

struct People
{
	int age;
	char name[100]; // 這裏若是用指針,下面用 strcpy 賦值時會報段錯誤
}; // 分號必須有

int main()
{
	struct People p = {20, "lisi"}; // 使用時,struct People 是一個總體
	printf("%d, %s\n", p.age, p.name); // 用點訪問結構體成員
	struct People *pp = &p;
	pp->age = 88;
	strcpy(pp->name, "jack"); // C 語言須要用 strcpy 函數實現字符串拷貝
	printf("%d, %s\n", p.age, p.name);

	return 0;
}

結構體成員變量的兩種訪問方式

用句點形式訪問(結構體變量)

結構體變量聲明後,能夠直接用句點形式訪問。函數

struct People p = {20, "lisi"};
p.age = 88;

用箭頭訪問(結構體指針變量)

定義指向結構體的指針後,能夠經過箭頭來訪問成員變量。spa

struct People p = {20, "lisi"};
struct People * pp = &p;
pp->age = 88; // 等價於 (*pp).age

內存對齊

對於 32 位數據總線的機器(例如 80386),雖然對內存仍然是按照字節尋址,但每次內存操做都固定傳輸 32 位數據。若是每次數據傳輸都連續且不重疊,效率是最高的。因此操做系統把內存按照數據總線的位數劃分爲獨立單元,對於 32 位數據總線的機器每一個單元是 4 個字節。每一個單元都完整的分配給一個程序。操作系統

C 語言的 struct 結構體中,能夠放各類類型、不一樣長度的數據,能夠看作一個數據包。爲了在程序內部提升內存訪問效率,也須要對齊內存。指針

下面的示例,struct People 中的第一個變量 sex 會對齊內存,第二個變量 age 緊隨其後,總共佔了三個字節,空餘一個字節。以後的 no 佔用 4 個字節,若是直接放在 sex 後面保存,則訪問 no 時須要兩次對內存的操做。爲了提升時間效率,C 編譯器會把 no 變量對齊內存,這樣 no 跟 sex 之間會有一個字節的空白。code

#include <stdio.h>

struct People {
	char sex; // 1 字節
	short age; // 2 字節,此時兩字節對齊,前面空一個字節
	int no; // 4 字節,此時4字節對齊,前面空一個字節
};

int main()
{
	struct People p = {'m', 66, 1234567};
	printf("%d\n", sizeof(p)); // 8 個字節
}

下面的例子中,少了一個變量,但由於字節對齊的緣由,存儲空間並無減小:xml

#include <stdio.h>

struct People {
	char sex; // 1 個字節
	int no; // 4 個字節,前面空 3 個字節
};

int main()
{
	struct People p = {'M', 1234567};
	printf("%d\n", sizeof(p)); // 仍是 8 個字節
}

而這個例子中,由於結構體中變量的順序發生改變,致使空間膨脹:對象

#include <stdio.h>

struct People {
	char sex; // 1 個字節
	int no; // 4 個字節,前面空 3 個字節
	short age; // 2 個字節,後面空 2 個字節
};

int main()
{
	struct People p = {'m', 1234567, 66};
	printf("%d\n", sizeof(p)); // 這裏是 12 個字節
}
相關文章
相關標籤/搜索