stddef.h
<stddef.h> 定义标准类型和宏:size_t、ptrdiff_t、NULL、offsetof 等。这些定义是 C 标准库的基础,几乎所有其他头文件都依赖它。理解这些类型和宏,是编写可移植 C 代码的前提。
主要定义
#include <stddef.h>
/* 类型 */
size_t; /* 无符号整数,sizeof 的结果类型 */
ptrdiff_t; /* 有符号整数,指针差值类型 */
/* 宏 */
NULL; /* 空指针常量:((void*)0) 或 0 */
/* 函数 */
offsetof(type, member); /* 成员在结构体中的偏移量 */
size_t
#include <stddef.h>
size_t len = strlen("Hello"); /* 5 */
size_t size = sizeof(int); /* 4 */
/* 数组索引 */
for (size_t i = 0; i < n; i++) {
/* ... */
}
size_t 是无符号类型,注意与有符号类型比较:
int n = -1;
if (n < sizeof(int)) { /* 警告:有符号与无符号比较 */
/* n 提升为很大的 size_t,条件为假 */
}
ptrdiff_t
int arr[10];
int *p1 = &arr[2];
int *p2 = &arr[7];
ptrdiff_t diff = p2 - p1; /* 5 */
offsetof
#include <stddef.h>
struct Point {
int x;
int y;
char label;
};
printf("%zu\n", offsetof(struct Point, x)); /* 0 */
printf("%zu\n", offsetof(struct Point, y)); /* 4 */
printf("%zu\n", offsetof(struct Point, label)); /* 8 */
NULL
int *p = NULL; /* 空指针 */
if (p == NULL) {
printf("Pointer is null\n");
}
/* C 中 NULL 通常是 ((void*)0) 或 0 */
/* C++ 中 NULL 是 0 */
常见错误
size_t 下溢:
size_t i = 0;
while (i >= 0) { /* 永远为真:size_t 无符号 */
/* ... */
i--;
}
/* 正确 */
for (size_t i = n; i-- > 0; ) {
/* i 从 n-1 到 0 */
}
offsetof 误用:
/* offsetof 只能用于标准布局的结构体 */
/* 不能用于位域 */
struct Bad {
int a : 4;
};
/* offsetof(struct Bad, a); */ /* 未定义行为 */
最佳实践
- 数组大小、索引用
size_t - 指针差值用
ptrdiff_t - 空指针用
NULL offsetof用于序列化、内存池- 注意无符号类型的下溢