在 C 语言中,sizeof
和 strlen
是两个完全不同的概念,虽然它们都可能用于处理字符串,但用途、计算方式和返回值有本质区别。
🔍 一、基本定义
函数/操作符 | 类型 | 说明 |
---|---|---|
sizeof |
操作符(Operator) | 计算数据类型或变量所占的内存字节数,在编译时确定。 |
strlen |
函数(Function) | 计算字符串中字符的个数(不包括末尾 \0 ),在运行时计算。 |
📌 二、核心区别对比
特性 | sizeof |
strlen |
---|---|---|
类型 | 操作符(编译时求值) | 函数(运行时求值) |
头文件 | 不需要 | #include <string.h> |
计算内容 | 占用内存大小(字节) | 字符个数(不含 \0 ) |
是否包含 \0 |
是(如果是字符数组) | 否 |
参数类型 | 任意类型(int, array, struct, pointer 等) | 只能是 const char* (字符串指针) |
对指针的操作 | 返回指针本身大小(如 4 或 8 字节) | 返回指向的字符串长度 |
遇到 \0 是否停止 |
否(它不关心内容) | 是(\0 是结束标志) |
✅ 三、代码示例说明
示例 1:字符数组
c
char str[] = "hello";
表达式 | 值 | 说明 |
---|---|---|
sizeof(str) |
6 |
"hello" + \0 = 6 字节 |
strlen(str) |
5 |
只算 'h','e','l','l','o' ,不包含 \0 |
示例 2:字符指针
c
char *p = "hello";
表达式 | 值 | 说明 |
---|---|---|
sizeof(p) |
8 (64位系统)或 4 (32位) |
指针本身的大小 |
strlen(p) |
5 |
字符串 "hello" 的长度 |
示例 3:固定长度数组(含未使用空间)
c
char buf[100] = "hi";
表达式 | 值 | 说明 |
---|---|---|
sizeof(buf) |
100 |
整个数组占 100 字节 |
strlen(buf) |
2 |
实际字符串 "hi" 长度为 2 |
⚠️ 即使只用了 3 字节(包括
\0
),sizeof
仍是 100。
示例 4:纯二进制数据(非字符串)
c
unsigned char data[32]; // 用于存储哈希值等二进制数据
表达式 | 值 | 说明 |
---|---|---|
sizeof(data) |
32 |
正确:获取字节数 |
strlen(data) |
未定义行为 | ❌ 危险!因为 data 中可能没有 \0 ,strlen 会一直找下去,直到内存越界 |
🛑 四、常见错误与陷阱
❌ 错误 1:用 strlen
处理非字符串二进制数据
c
uint8_t hash[32] = { /* 二进制数据 */ };
size_t len = strlen(hash); // ❌ 危险!可能无限循环或崩溃
✅ 正确做法:
c
size_t len = sizeof(hash); // ✅ 正确获取长度
❌ 错误 2:混淆指针和数组的 sizeof
c
void func(char arr[]) {
printf("%zu\n", sizeof(arr)); // ❌ 输出的是指针大小(8),不是数组大小
}
因为 arr
在函数参数中退化为指针。
✅ 正确做法:传长度参数
c
void func(char arr[], size_t len) {
printf("实际长度: %zu\n", len);
}
✅ 五、何时使用?
场景 | 推荐使用 |
---|---|
获取数组、结构体、变量占用的内存大小 | sizeof |
获取字符串中"有效字符"个数(如 "hello" 是 5) |
strlen |
处理二进制数据(如加密、哈希、网络包) | sizeof (strlen 不安全) |
动态分配内存时计算大小 | sizeof |
判断字符串是否为空 | strlen(str) == 0 或 str[0] == '\0' |
✅ 六、总结口诀
🔹
sizeof
看"内存大小" ,不管内容,编译时就知道。🔹
strlen
看"字符串长度" ,找\0
为止,运行时才知。🔹 二进制数据用
sizeof
,字符串长度用strlen
。🔹 数组用
sizeof
安全,指针用sizeof
要小心。
🧪 小测试
c
char s[] = "C\0language";
printf("sizeof: %zu\n", sizeof(s)); // 输出?
printf("strlen: %zu\n", strlen(s)); // 输出?
✅ 答案:
sizeof(s)
→11
("C" +\0
+ "language" +\0
= 1 + 1 + 8 + 1 = 11)strlen(s)
→1
(遇到第一个\0
就停止)
掌握 sizeof
和 strlen
的区别,是写出安全、正确 C 代码的基础。