C语言中sizeof和strlen的区别

在 C 语言中,sizeofstrlen 是两个完全不同的概念,虽然它们都可能用于处理字符串,但用途、计算方式和返回值有本质区别。


🔍 一、基本定义

函数/操作符 类型 说明
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 中可能没有 \0strlen 会一直找下去,直到内存越界

🛑 四、常见错误与陷阱

❌ 错误 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
处理二进制数据(如加密、哈希、网络包) sizeofstrlen 不安全)
动态分配内存时计算大小 sizeof
判断字符串是否为空 strlen(str) == 0str[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 就停止)

掌握 sizeofstrlen 的区别,是写出安全、正确 C 代码的基础。

相关推荐
Mr_sun.4 小时前
Day04_苍穹外卖——套餐管理(实战)
开发语言·python
南棱笑笑生4 小时前
20250910在荣品RD-RK3588-MID开发板的Android13系统下修改短按power按键的休眠/唤醒为关闭/打开背光
开发语言·python·rockchip
悠悠~飘4 小时前
php学习(第二天)
开发语言·学习·php
oioihoii4 小时前
构造函数和析构函数中的多态陷阱:C++的隐秘角落
java·开发语言·c++
索迪迈科技5 小时前
java后端工程师进修ing(研一版‖day42)
java·开发语言·学习·算法
Chris.Yuan7705 小时前
Java代理模式详解
java·开发语言·代理模式
Forever_Hopeful5 小时前
【C 语言生成指定范围随机数(整数 + 小数):原理、实现与避坑指南】
服务器·c语言·开发语言
午夜游鱼6 小时前
Go 泛型实战:一行代码封装 sync.Pool,性能与安全兼得
开发语言·安全·golang
mit6.8246 小时前
[邮件服务器core] 安全通信(SSL/TLS) | OpenSSL库管理 | 服务端安全SECURITY.md
c语言·github