1. 指针运算中的经典误区
在C语言开发中,sizeof和strlen这两个看似简单的操作符/函数,却成为无数程序员踩坑的重灾区。我见过太多工作3-5年的开发者,面对指针和数组混合使用时仍然会犯基础错误。最典型的例子就是:
c复制char str[] = "hello";
char *p = str;
printf("%d %d", sizeof(p), strlen(p));
这段代码的输出结果会让90%的初学者感到意外。实际上,sizeof(p)返回的是指针变量本身的大小(32位系统通常是4,64位系统是8),而strlen(p)才会计算字符串的实际长度5。这种认知偏差源于对底层内存模型的误解。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从内存模型看本质区别
2.1 sizeof的编译期特性
sizeof是C语言中的一元操作符(不是函数!),它在编译阶段就确定结果。当作用于指针时:
- 对基本类型指针(int*, char*等):返回指针变量本身的存储大小
- 对数组名:返回整个数组的字节大小(除非数组名已退化为指针)
关键点在于:sizeof从不关心指针指向的内容,它只计算变量本身的存储需求。这也是为什么在函数参数传递数组时,用sizeof获取数组长度会失效——数组名此时已退化为指针。
2.2 strlen的运行时行为
strlen是标准库函数,必须程序运行时才能工作。它的实现原理是从给定内存地址开始,逐个字节检查直到遇到'\0'。这意味着:
- 必须保证字符串以null结尾
- 时间复杂度是O(n)
- 对非字符串指针使用会导致内存越界
一个有趣的实现细节:glibc中的strlen会先用long类型对齐指针,然后每次检查8字节(64位系统),这比逐字节检查快得多。
3. 典型场景深度解析
3.1 数组与指针的sizeof差异
c复制char arr[20] = "test";
char *p = arr;
printf("%zu %zu\n", sizeof(arr), sizeof(p)); // 输出20和8(64位系统)
这里arr作为数组名,sizeof返回整个数组大小;而p是指针,sizeof只计算指针变量大小。这个差异在函数参数传递时尤为关键——数组作为参数时会退化为指针。
