對於複雜的數據類型(例如學生、汽車等),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 個字節 }