結構體定義與聲明分離
// header.h
#ifndef HEADER_H
#define HEADER_H
struct Student; // 前向聲明 (不完整類型)
void input_student(struct Student *s);
void print_student(const struct Student *s);
#endif
// student.c
#include "header.h"
struct Student { char name[20]; int age; float score; };
void input_student(struct Student *s) { scanf("%s %d %f", s->name, &s->age, &s->score); }
void print_student(const struct Student *s) { printf("%s %d %.1f\n", s->name, s->age, s->score); }
// main.c
#include "header.h"
int main() {
struct Student s;
input_student(&s);
print_student(&s);
return 0;
}
typedef 簡化類型名
typedef struct {
char name[20];
int age;
} Student;
Student s1 = {"Alice", 20};
Student s2 = s1; // 整體賦值合法
s1.age = 21; // 修改副本不影響 s2
結構體對齊與大小計算
struct A { char c; int i; }; // 8 字節 (c+3填充+i)
struct B { int i; char c; }; // 8 字節 (i+c+3填充)
struct C { double d; char c; }; // 16 字節 (d(8)+c(1)+7填充) - 最大對齊 8
#pragma pack(1)
struct D { char c; int i; }; // 5 字節 (無填充)
#pragma pack()
位域優化存儲
struct Flags {
unsigned int ready : 1;
unsigned int error : 1;
unsigned int mode : 2; // 0-3
unsigned int reserved : 28;
}; // 總共 4 字節
柔性數組成員
struct Buffer {
size_t len;
char data[]; // C99 柔性數組,必須為最後一個成員
};
struct Buffer *buf = malloc(sizeof(struct Buffer) + 100);
buf->len = 100; // 使用 buf->data[0..99]
多文件項目組織建議
- 每個結構體一對
.h/.c,.h 含前向聲明與操作函數原型
.c 含完整定義與函數實現
- 主程序只包含
.h,解耦實現細節
- 全局變量盡量避免,若需共享用
extern 在 .h 聲明,.c 定義