結構體:
聚合資料型別是指,能夠同時儲存超過乙個的單獨資料,c語言中有兩個聚合資料型別,陣列和結構體。陣列中儲存的型別必須相同,元素通過下標和指標引用來訪問的。
結構體也是一些值的集合,但是結構體中每個元素的值的型別可以不同,每個元素都有自己的名字,和整數字元一樣,結構體也是標量型別
結構體宣告:
structtagvariable-list;結構體宣告要包含所有的成員的型別和名字
struct tag people;其中,tag時標簽字段,可以在後續的宣告中使用tag代表成員列表:
struct tag animal;此處的宣告和上面的people一樣,animal和people對於編譯器來說,是兩個不同的型別的。
如果需要定義相同的型別,可以通過typedef來建立新型別:
typedef struct animal;現在animal是一新的結構體型別,可以直接使用他進行賦值
animal dog;結構體的成員:結構體的成員可以時標量,指標,和其他結構體等等,但是不可以是自身型別的成員,即自己。結構體成員可以通過點號訪問
#include typedef struct animal;執行結果:int main()
; printf("%s", dog.name);
return 0;
}
如果是指向結構體的指標,可以先解引用操作,然後在使用點操作符,c有個快捷的方法,使用 -> 訪問結構體指標指向的結構體成員,上面**可以如下改寫:
animal dog = ;結構體時不可以包含自身型別的成員的,不過可以包含指向自己型別的指標的。animal *ptr = &dog;
printf("%s", ptr -> name);
#include struct self animal;執行結果:int main()
; struct self cat = ;
printf("%s", cat.selfptr -> name);
return 0;
}
注意:下面的這種宣告是非法的,因為型別名直到宣告結束才定義
typedef struct self;解決方法是新增乙個結構標籤。
typedef struct self animal;如果兩個結構體相互依賴引用,乙個結構體包含另乙個結構體,另乙個結構體包含這個結構體。那麼可以使用不完整宣告,先宣告乙個結構體作為識別符號,然後使用他,然後把成員和識別符號關聯。
//宣告表示符,在a中使用結構體的初始化,類似陣列,大括號內部包含逗號分割的初始值,如果初始值列表不夠用,剩餘的結構成員將使用預設值初始化。struct b;
struct a ;
//關聯成員
struct b ;
struct me = ;結構體的儲存分配:
由於結構體類別的成員的型別可以不一樣,編譯器在給成員列表分配記憶體時,乙個接著乙個的分配,只有當儲存成員需要滿足邊界對齊時,成員之間會出現儲存間隙。系統禁止在乙個結構的起始位置跳過幾個位元組來滿足邊界對齊要求,因此所有的結構的起始儲存位置,必須是邊界要求最嚴格的資料型別所要求的位置,如下:
#include int main()可以通過重新排序成員,讓邊界對齊要求高的先出現,如上執行:stc1;
struct stc2;
printf("%lu %lu", sizeof(stc1), sizeof(stc2));
return 0;
}
int型別佔四個位元組,char佔乙個位元組,因為要從起始位置對齊,所以stc1的第乙個char佔4位元組,而stc2中,age佔四個位元組,ch1和ch2在一起佔四個位元組。sizeof可以返回乙個long unsigned int表示整個結構體長度。
stddef.h巨集 offsetof(type, member) 返回指定成員,距離結構開始偏移幾個位元組。
#include #include int main()執行:; struct stc2 ;
printf("%lu %lu", offsetof(struct stc1, ch2), offsetof(struct stc2, ch2));
return 0;
}
C和指標 第十章 結構和聯合 (二)
結構體傳值 typedef struct produts 傳入指標,加const修飾,防止程式修改 void test produts const ptr 位段 結構體可以實現位段,位段的宣告和結構體型別,但是成員是多個位的字段,不同長度的字段儲存在乙個或多個整形變數中。位段的型別必須宣告成int,...
第十章 陣列和指標
陣列初始化 當初始化列表中的值少於陣列元素個數時,編譯器會把剩餘的元素都初始化為0 個數多於陣列元素個數時,會視為錯誤 省略陣列中括號中的數字,編譯器會根據初始化列表中的專案來確定陣列的大小。days是陣列 sizeof days是整個陣列的大小 sizeof day 0 是陣列中乙個元素的大小 c...
C Primer Plus 第十章 陣列和指標
int sum int ar,int n intsum int int intsum int ar,int n intsum int int 指標減去乙個整數 指標必須是第乙個運算物件 相加的逆操作。遞減指標 逆操作遞增 指標求差 可以計算兩個指標的差值。通常,求差的兩個指標分別指向同乙個陣列的不同...