在C语言编程中,sizeof 和 strlen 是两个极易混淆的常用工具,尤其在字符串处理、数组操作、网络编程缓冲区赋值场景中,绝大多数新手都会踩坑。很多人写代码多年,依然分不清二者的底层逻辑,常常出现缓冲区溢出、数据发送冗余、字符串截断等问题。
本文结合大家常用的UDP测试字符串案例,从零讲透二者的本质、用法、区别以及工程实战中的避坑技巧,看完彻底告别混淆。
一、基础定义:本质完全不同
1. sizeof:运算符,计算内存占用大小
sizeof 是C语言内置运算符,并非函数 ,编译阶段即可完成计算。它的核心作用是:统计变量、数据类型、数组在内存中占用的总字节数,不关注内存中存储的内容是什么。
核心特性:
-
包含字符串末尾的结束符 \0
-
适用于所有数据类型(int、char、数组、结构体等)
-
编译期计算,运行时无开销
2. strlen:库函数,计算字符串有效长度
strlen 是标准库函数(<string.h>) ,需要程序运行后才能执行计算。它的核心作用是:统计字符串中有效可见字符的个数。
核心特性:
-
不包含 字符串结束符 \0
-
仅适用于字符串(char * / char\[\])
-
运行时逐字符遍历,直到遇到 \0 停止统计
二、实战案例:UDP测试字符串精准验证
沿用网络编程常用的测试代码,直观对比二者结果:
cs
#include <stdio.h>
#include <string.h>
int main(void)
{
// UDP测试数据字符串
char send_msg[] = "UDP test data";
printf("strlen 有效长度:%d\n", strlen(send_msg));
printf("sizeof 内存总大小:%d\n", sizeof(send_msg));
return 0;
}
运行输出结果
cs
strlen 有效长度:13
sizeof 内存总大小:14
结果拆解
字符串 UDP test data 包含13个可见有效字符,系统会自动在字符串末尾补隐藏结束符 \0:
-
strlen :只统计13个可见字符,忽略末尾
\0,结果为13 -
sizeof :统计整个数组内存,13个有效字符 + 1个
\0,结果为14
三、核心区别对照表(一目了然)
| 对比维度 | sizeof | strlen |
|---|---|---|
| 本质属性 | 编译期运算符 | 运行期库函数 |
| 计算内容 | 内存总字节大小 | 字符串有效字符个数 |
| 是否包含\0 | 包含 | 不包含 |
| 适用范围 | 所有数据类型、数组、结构体 | 仅字符串(以\0结尾) |
| 依赖头文件 | 无需头文件 | 必须引入 <string.h> |
四、高频易错场景:网络编程重点避坑
很多新手在UDP/TCP网络发送数据时,会误用 sizeof 导致业务bug,这是工程中最高频的问题。
错误写法(冗余数据)
cs
// 错误:多发送一个空字符\0
sendto(fd, send_msg, sizeof(send_msg), 0, ...);
问题:原本只需发送13字节有效数据,此时发送14字节,末尾多出一个空字符,可能导致接收端数据解析异常、日志乱码。
正确写法(标准网络编程)
cs
// 正确:只发送有效数据长度
sendto(fd, send_msg, strlen(send_msg), 0, ...);
五、补充进阶考点(面试必问)
1. ++指针形式++的字符串差异
cs
char *msg = "UDP test data";
// strlen 依然是13(有效字符数不变)
// sizeof 结果为4/8(32/64位系统,计算的是指针变量本身大小,不是字符串)
关键结论:数组名代表整个内存块,指针仅代表地址,二者 sizeof 结果完全不同。
2. 手动添加\0的陷阱
如果字符串未正常结尾(无 \0),strlen 会内存越界,一直向后遍历随机内存,导致结果随机、程序崩溃,而 sizeof 不受影响。
六、最终总结口诀
给大家总结一句极简口诀,永久记住二者区别:
sizeof看内存,全包零结束;strlen看内容,只算有效数。
-
做内存开辟、缓冲区大小定义,用 sizeof
-
做字符串统计、网络数据发送、内容处理,用 strlen