struct Birthday { int year, month, day; };
struct Employee {
int id;
char *name;
float salary;
struct Birthday birth; // 巢狀結構
};
struct Employee e1 = {100, "webabcd", 100.5f, {1980, 2, 14}};
struct Employee e2 = {.id = 101, .name = "wanglei"}; // C99 指定初始化
struct Employee *p = &e1;
printf("%s\n", p->name); // 等同 (*p).name
struct Employee team[2] = {e1, e2};
struct Employee *ptr = team; // 指向首元素
ptr[1].id == team[1].id; // 等價
結構體較大時,**傳指標**避免整體複製開銷:
void print_emp(const struct Employee *e); // const 防誤改
成員**共用同一塊記憶體**,大小 = 最大成員大小 (對齊後)。
union Data {
int i;
float f;
char str[10];
} u;
u.i = 0x61626364; // 'a','b','c','d' (小端序)
printf("%c%c%c%c\n", u.str[0], u.str[1], u.str[2], u.str[3]); // d c b a
enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT };
enum Weekday today = WED; // 值為 3
if (today == 3) ... // 可直接與整數比較
enum ErrorCode { OK = 0, ERR_IO = -1, ERR_MEM = -2, ERR_NET = -3 };
enum { MAX_CONN = 1024, BUF_SIZE = 4096 };
typedef int Integer;
typedef int *IntPtr;
typedef char Name[20];
typedef char *String;
typedef struct Employee Emp; // 結構體別名
Integer a = 10;
IntPtr p = &a;
Name n = "webabcd";
String s = "hello";
Emp e = {1, "web", 100.0f, {1990,1,1}};
| 特性 | #define | typedef |
|---|---|---|
| 處理階段 | 預處理 (文字替換) | 編譯 (型別系統) |
| 指標宣告 | #define PTR int* → PTR a,b; (a是指標,b是int) | typedef int* PTR; → PTR a,b; (皆為指標) |
| 作用域 | 檔案級 (無視區塊) | 遵循區塊作用域 |
| 除錯資訊 | 無 (符號表不見) | 保留型別名稱 |
struct AlignTest {
char c; // 1 byte
// 3 bytes padding
int i; // 4 bytes
// 共 8 bytes
};
// 重新排序可省空間:
struct Better {
int i; // 4
char c; // 1
// 3 padding → 共 8 (同樣大小,但某情況可緊湊)
};
使用 #pragma pack(n) 或 __attribute__((packed)) 可控制對齊,但可能影響存取效能。