本篇文章主要是對結構體數據類型的一個知識擴展,包含了結構體的嵌套使用、結構體數組、結構體指針。
在學習結構體時,有提到結構體裡面的成員可以是基本數據類型,也可以是數組、結構體等其他類型。
那麼,接下來就說一下,在定義結構體中嵌套另一個結構體的兩種方法。
第一種方法:獨立結構嵌套。
分别定義了兩個結構,然後将其中一個結構嵌套在另一個結構中。
struct Birthday{
int dd;
int mm;
int yy;
};
struct Student{
char *name;
struct Birthday birthday;
};
這裡需要注意兩個點:
A. 嵌套的結構體(Birthday)必須要在被嵌套的結構體(Student)之前定義,如果順序反了,編譯器是不會通過的,會給出如下報錯。
error: field 'birthday' has incomplete type
錯誤:字段'birthday'的類型是不完整的
這是因為C語言程序的編譯是自上而下執行的。
如果兩個結構體的順序寫反了,編譯器首先是執行到 Student 結構,看到裡面的 Birthday 結構聲明的變量,因為結構體是程序員自定義的數據類型,系統是不提供的,而這裡的 Birthday 結構還沒有進行定義,所以C語言是不認識這種數據類型,就會給出報錯。
B. 在定義結構中嵌套另一個結構,如果沒有定義結構的别名,struct 和結構名稱必須同時出現,才表示為結構體類型。
同時在結構體中,一個完整的成員必須包含類型以及變量名,缺一不可。
第二種方法:嵌入式嵌套
這種方式就不用考慮兩個獨立結構誰先誰後的問題,隻需要在被嵌套的結構(Student)中以嵌入的方式定義嵌套的結構(Birthday)類型。
struct Student{
char *name;
struct Birthday{
int dd;
int mm;
int yy;
} birthday;
};
和前面的獨立結構嵌套相比,如果嵌套的結構體比較少,可以采用這種方式。但是要嵌套好幾個結構體,建議還是使用獨立嵌套的方式,否則會導緻代碼看上比較冗長複雜。
嵌套結構體的初始化和訪問方式如下:
// 變量初始化
Struct Student s1 = {"張三", {1,1, 2000}};
// 訪問 Birthday 結構中 dd 成員;
s1.birthday.dd; // 1
關于結構體嵌套,還有一個非常重要的問題:所定義的結構體能将自身類型作為成員嗎?
struct A{
struct A a;
} aa;
答案是不能的,像上面這種寫法是錯誤的。
嵌套的是定義結構自身的變量,就會出現這種情況:aa.a.a.a.a.a.a……就會一直無限循環下去。
在内存分配的時候,由于無法确定所定義的結構體地長度,就不會被系統允許。
但是如果想要引用自身,也不是不行,可以通過指針來進行使用。
指針類型,無論是什麼類型的指針,所占的内存大小都是固定的。
struct A{
struct A *a;
} aa;
結構體的指針類型的聲明方式如下:
struct 結構名稱 *變量名;
結構體的指針聲明和基本數據類型是一樣,都需要帶上尋址運算符(&)。
struct Student{
char *name;
int age;
};
struct Student s1 = {"張三", 15};
struct Student *ps1 = &s1;
通過指針類型訪問結構體中的成員的方式有兩種。
第一種,通過訪問運算符。
(*ps1).name; // 張三
由于訪問運算符的優先級比較高,所以需要對 *ps1 添加上括号。
如果沒有加上括号,先執行的是 ps1.name,而 ps1 是一個指針變量,所存儲的是結構體 s1 的内存地址。
第二種方式,通過箭頭運算符 -> 進行訪問。
箭頭運算符是C語言結構體的一種特殊的運算符,可以直接從結構體指針變量中訪問結構體裡面的成員。
ps1->age; // 15
數組,是用來存儲相同類型的集合。
結構體數組,用來存儲同一個結構類型的不同數據,也叫作結構的集合。
例如,定義了一個學生的結構,而一個班裡面又有很多個學生。總不能一個一個地去聲明不同數據的學生結構類型,這樣做就是顯得太麻煩了。
這時候,我們就可以用一個數組變量來存儲起來。
結構體數組的定義方式如下:
struct Student{
char *name;
int age;
} class[5] = {
{"孫悟空", 500};
{"唐僧", 33};
{"豬八戒", 101};
{"沙僧", 98};
{"白龍馬", 102};
};
定義的結構體數組變量 class 中括号裡面的數字,如果有進行初始化操作,即數組中全部元素都已經賦值,則可以不用帶。系統會自動根據數組裡面的内容,給該數組确定相應的長度。
如果沒有進行初始化,則必須要帶上數組長度,否則就會出錯。
結構體數組的訪問方式也比較簡單,通過數組索引值取出相應的結構,再通過訪問運算符進行訪問。
例如:我們想知道唐僧的年齡。
class[1].age; // 33
以上就是關于構造數據類型,結構體的知識擴展内容,包括了嵌套使用、結構體指針以及結構體數組的知識。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!