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 代码的基础。

相关推荐
心无旁骛~18 小时前
python多进程multiprocessing——spawn启动方式解析
开发语言·python
不想写笔记18 小时前
C语言 操作符(下)
c语言·笔记
小石头 1008619 小时前
【Java】String类(超级详细!!!)
java·开发语言·算法
conkl19 小时前
Python中的鸭子类型:理解动态类型的力量
开发语言·python·动态·鸭子类型·动态类型规划
小小8程序员19 小时前
swift的inout的用法
开发语言·ios·swift
祈澈菇凉19 小时前
Next.js 零基础开发博客后台管理系统教程(一):环境搭建与项目初始化
开发语言·javascript·ecmascript
wjs202419 小时前
Go 语言切片(Slice)
开发语言
誰能久伴不乏19 小时前
为什么 TCP 服务端重启会出现 “Address already in use”问题解析
linux·服务器·c语言·网络·c++·tcp/ip
muyouking1119 小时前
Rust Slice 完全指南:从基础用法到 3D 场景实战
开发语言·3d·rust
VekiSon19 小时前
gdb工具介绍
linux·c语言