<stddef.h> 定義 C 標準庫通用的基礎類型與宏,眾多頭文件會重複包含它。核心內容:
size_t、ptrdiff_t、wchar_tNULLoffsetofsizeof 運算符返回類型%zu (C99)%td (C99)L'x'、寬字符串:L"hello"<wchar.h> 使用寬字符串函數((void*)0) 或 0 或 0Lnullptr 替代
size_t offsetof(type, member-designator);
type 中成員 member 相對結構體起始地址的位元組偏移((size_t)&(((type *)0)->member)) (利用空指針解引用計算偏移,未定義行為但編譯器內置支持)
#include <stddef.h>
#include <stdio.h>
struct User {
char name[50];
char alias[50];
int level;
double score;
struct User *next;
};
int main() {
printf("size_t 大小: %zu 位元組\n", sizeof(size_t));
printf("ptrdiff_t 大小: %zu 位元組\n", sizeof(ptrdiff_t));
printf("wchar_t 大小: %zu 位元組\n", sizeof(wchar_t));
printf("\n結構體 User 佈局:\n");
printf("總大小: %zu\n", sizeof(struct User));
printf("name 偏移: %zu\n", offsetof(struct User, name));
printf("alias 偏移: %zu\n", offsetof(struct User, alias));
printf("level 偏移: %zu\n", offsetof(struct User, level));
printf("score 偏移: %zu\n", offsetof(struct User, score));
printf("next 偏移: %zu\n", offsetof(struct User, next));
// 驗證對齊
struct User u;
printf("\n實際地址驗證:\n");
printf("&u = %p\n", (void*)&u);
printf("&u.level = %p (偏移 %td)\n", (void*)&u.level, (char*)&u.level - (char*)&u);
return 0;
}
size_t 大小: 8 位元組 ptrdiff_t 大小: 8 位元組 wchar_t 大小: 4 位元組 結構體 User 佈局: 總大小: 120 name 偏移: 0 alias 偏移: 50 level 偏移: 100 score 偏移: 104 next 偏移: 112 實際地址驗證: &u = 0x7ffc12345670 &u.level = 0x7ffc123456d4 (偏移 100)
注意:double 8 位元組對齊,導致 level (4 位元組) 後有 4 位元組填充,score 從 104 開始。
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
// 用法: 從鏈表節點指針獲取包含結構體指針
struct ListNode { struct ListNode *next; };
struct MyStruct { int data; struct ListNode node; };
struct ListNode *node_ptr = ...;
struct MyStruct *obj = container_of(node_ptr, struct MyStruct, node);
#include <assert.h>
// C11 _Static_assert
_Static_assert(offsetof(struct User, level) == 100, "level 偏移量變更");
_Static_assert(sizeof(struct User) == 120, "結構體大小變更");
void serialize_user(const struct User *u, unsigned char *buf) {
memcpy(buf + offsetof(struct User, name), u->name, 50);
memcpy(buf + offsetof(struct User, alias), u->alias, 50);
memcpy(buf + offsetof(struct User, level), &u->level, sizeof(int));
// ...
}
| 項目 | 32 位系統 | 64 位系統 |
|---|---|---|
| size_t / ptrdiff_t | 4 位元組 | 8 位元組 |
| 指針大小 | 4 | 8 |
| 結構體對齊 | 通常 4/8 | 通常 8/16 |
| wchar_t | 2 或 4 | 通常 4 |
代碼中不要假設具體大小,始終使用 sizeof 和 offsetof。