簡單型態(整數、實數、字元)與陣列(同質元素集合)無法描述異質資料群組。
現實場景:住宿登記(姓名、性別、職業、年齡、身分證號)、成績單(班級、學號、姓名、多科分數)、通訊錄(姓名、部門、地址、郵遞區號、電話、Email)。
結構體:集中不同型態成員於一體,形成異質資料集合。
struct 結構體名 {
成員列表
};
struct stu { // 定義類型
char name[20];
char sex;
long num;
float score[3];
};
struct stu student1, student2; // 定義變數
struct stu student3, student4; // 同類型可繼續定義更多變數
struct data {
int day, month, year;
} time1, time2; // 同步定義變數
struct data time3, time4; // 後續仍可用類型名定義更多
struct {
char name[20];
char sex;
long num;
float score[3];
} person1, person2; // 直接定義變數
// 缺點:無類型名,無法在其他處復用此結構定義
語法:結構體變數.成員名
struct data { int day, month, year; } time1, time2;
time1.day = 15;
time1.month = 8;
time1.year = 2024;
// 等價於三個獨立 int 變數操作
每個結構體變數擁有獨立的成員副本,互不干擾。
語法:定義時以大括號依成員順序提供初值。
struct stu {
char name[20];
char sex;
long num;
float score[3];
};
struct stu student = {"LiPing", 'F', 970541, 98.5, 97.4, 95};
結果:
三種定義形式皆可在定義時初始化。
因成員型態不一,採字串輸入 + 型態轉換:
char temp[20];
gets(student.name); // 姓名直接讀字串
student.sex = getchar(); // 性別讀單字元
gets(temp);
student.num = atol(temp); // 學號字串轉長整數
for (i = 0; i < 3; i++) {
gets(temp);
student.score[i] = atof(temp); // 分數字串轉浮點數
}
輸出:同樣需逐成員獨立輸出,不可整體輸出。
結構體成員可為另一結構體類型。
struct date {
int day, month, year;
};
struct stu {
char name[20];
struct date birthday; // 巢狀結構體成員
long num;
};
struct stu person;
person.name = "John";
person.birthday.day = 15;
person.birthday.month = 8;
person.birthday.year = 2000;
person.num = 12345;
存取鏈:person.birthday.day — 逐層使用點運算子。
// struct stu student = {"LiPing", 'F', 970541, 98.5, 97.4, 95};
// 記憶體連續儲存(含對齊填充):
[ L ][ i ][ P ][ i ][ n ][ g ][ \0 ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ] // name[20] 20 bytes
[ F ][ ? ][ ? ][ ? ] // sex + padding 4 bytes
[ 970541 (4 bytes) ] // long 4 bytes
[ 98.5 (4 bytes) ][ 97.4 (4 bytes) ][ 95.0 (4 bytes) ] // float[3] 12 bytes
// 總計約 40 bytes(視編譯器對齊策略)
struct stu *p = &student;
p->name = "Wang"; // 等價於 (*p).name = "Wang"
p->score[0] = 90.0;
-> 專用於指標存取成員,. 用於變數本體。
struct stu class[50]; // 50 位學生
class[0].name = "A";
class[1].score[2] = 88.5;
// 配合迴圈批次處理
struct flags {
unsigned int ready : 1; // 1 bit
unsigned int error : 1;
unsigned int mode : 2; // 2 bits (0-3)
unsigned int id : 28; // 剩餘 bits
};
// 總計 32 bits = 4 bytes,遠小於用獨立 int
適用於旗標、硬體暖存器映射、壓縮儲存。
變數.成員、指標->成員a = b),整體 I/O 非法