目錄
- 一、結構體的聲明
- 二、結構體的定義和初始化
- 三、結構體成員訪問
- 四、結構體傳參
- 五、函數調用的參數壓棧(了解)
在C語言中,我們知道數組是一組相同類型元素的集合,而結構體則更為靈活,它允許我們將不同類型的數據組合在一起,形成一個新的復合數據類型。本文將帶你全面了解結構體的基礎知識,從聲明定義到成員訪問,再到最后的結構體傳參。
一、結構體的聲明
結構體的聲明使用struct
關鍵字,其基本語法如下:
struct 結構體標簽 {類型 成員1;類型 成員2;// 更多成員...
};
與數組不同,結構體的成員可以是不同類型的變量。例如,我們可以創建一個學生結構體:
struct Stu {char name[20]; // 姓名int age; // 年齡float score; // 成績
};
聲明結構體后,我們可以創建該類型的變量:
struct Stu s; // 創建一個Stu類型的結構體變量s
當然我們也可以在聲明結構體的同時創建變量(此時創建的是全局變量(因為在{}外定義)):
struct Stu {char name[20];int age;float score;
} s1, s2; // 全局變量s1和s2
而上面的在main函數內部創建的則是局部變量。
二、結構體的定義和初始化
結構體的初始化與數組類似,使用花括號{}
進行初始化:
struct Stu s = {"張三", 18, 90.5};
當結構體嵌套時(即成員中包含另一個結構體),可以使用嵌套的花括號來對結構體進行初始化:
struct Date {int year;int month;int day;
};struct Student {char name[20];struct Date birthday; // 嵌套結構體
};struct Student stu = {"李四", {2000, 5, 20}};
三、結構體成員訪問
訪問結構體成員有兩種方式:
- 使用
.
操作符直接訪問:
struct Stu s;
strcpy(s.name, "王五");
s.age = 19;
s.score = 88.5;
- 當有結構體指針時,使用
->
操作符:
struct Stu s;
struct Stu *ps = &s;
ps->age = 20; // 等價于 (*ps).age = 20;
如在這里ps->age,表示的意思是ps先找到指向的結構體變量s,再找其成員變量age
四、結構體傳參
結構體作為函數參數傳遞時有兩種方式:
- 傳值調用:傳遞整個結構體對象的副本
void printStudent(struct Stu s) {printf("姓名: %s, 年齡: %d, 成績: %.1f\n", s.name, s.age, s.score);
}// 調用
printStudent(s);
- 傳址調用:傳遞結構體的指針
void printStudent(struct Stu *ps) {printf("姓名: %s, 年齡: %d, 成績: %.1f\n", ps->name, ps->age, ps->score);
}// 調用
printStudent(&s);
這兩種方式我們推薦使用傳址調用,原因如下:
- 效率更高:傳值調用需要臨時拷貝整個結構體,會消耗更多內存和時間。而傳址調用只需傳遞一個指針(32位系統4字節,64位系統8字節),大大提高了傳參效率。
- 功能更強大:通過指針可以直接修改原結構體的值,而傳值調用只能操作副本。
五、函數調用的參數壓棧(了解)
在函數調用過程中,參數會被"壓棧"(push onto the stack)。棧是一種先進后出(LIFO)的數據結構:
- 每次函數調用都會在內存的棧區開辟一段空間
- 參數通常從右向左依次壓棧
- 例如
Add(a, b)
調用時,先壓入b
,再壓入a
了解函數棧幀的創建和銷毀有助于深入理解函數調用機制,這相當于我們編程能力的"內功"。
結構體是C語言中非常重要的自定義數據類型,它允許我們將不同類型的數據組合成一個整體。通過本文,我們介紹了:
- 如何聲明和定義結構體
- 結構體的初始化和成員訪問方法
- 結構體傳參的兩種方式(優先使用傳址調用)
- 函數調用時的參數壓棧機制(了解)
掌握結構體的基礎知識是學習更高級數據結構的前提,也是編寫復雜程序的必備技能。在實際開發中,結構體經常與指針配合使用,能夠極大地提高程序的靈活性和效率。在下一章,我們將介紹一些實用的調試技巧,敬請期待!
作者其他文章鏈接:
初識C語言—人生若只如初見(完結撒花!)
[C語言初階]指針初階
[C語言初階]操作符
[C語言初階]掃雷小游戲
Gitee詳細使用教程