亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

C 语言 strlen 与 sizeof 深度解析:核心差异、陷阱避坑与最佳实践

strlen():运行时计算字符串长度

strlen() 定义于 <string.h>,返回以空字符 '\0' 结尾的字符串中字符数(不含终止符)。它从指针开始逐字节扫描,直到遇到 '\0',因此时间复杂度为 O(n)。

size_t strlen(const char *str);

sizeof:编译期/运行期获取对象占用字节数

sizeof 是一元运算符(非函数),用于获取类型或表达式的存储大小(字节数)。对静态类型在编译期求值;对变长数组(VLA)在运行期求值。不求值表达式(不执行副作用)。

sizeof(type)        // 类型大小
sizeof expression   // 表达式结果类型大小,不计算表达式
sizeof variable     // 变量占用字节数

核心差异对比表

特性strlen()sizeof
头文件string.h内置运算符,无需头文件
作用对象仅以 '\0' 结尾的字符数组/指针任意类型、变量、表达式
计算内容字符串逻辑长度(不含 '\0')对象占用内存字节数(含 '\0'、填充字节)
求值时机运行时(遍历字符串)编译期(VLA 除外)
返回类型size_tsize_t
空指针行为未定义行为(崩溃)不适用(作用于类型/变量)
数组退化参数退化为指针,仅见首元素地址作用于数组对象本身,得完整大小

语法与示例

strlen() 示例

#include <stdio.h>
#include <string.h>

int main(void) {
    char str[] = "January";
    printf("Length: %zu\n", strlen(str));   // 7
    return 0;
}

sizeof 示例

1) sizeof(类型)

printf("%zu\n", sizeof(double));   // 8(64 位系统)

2) sizeof(变量)

char c = 'S';
double d = 4.65;
printf("%zu %zu\n", sizeof(c), sizeof(d));   // 1 8

3) sizeof(表达式) —— 不求值

int a = 5;
printf("%zu\n", sizeof(a++));   // 4(int 大小),a 不变仍为 5

经典陷阱:数组退化导致的 sizeof 误用

void func(char arr[]) {          // 参数退化为 char*
    printf("%zu\n", sizeof(arr)); // 8(指针大小),非数组长度!
}

int main() {
    char str[] = "Hello";
    printf("%zu\n", sizeof(str)); // 6(含 '\0')
    func(str);                    // 传入后退化
    return 0;
}

对策:函数参数若需数组大小,必须显式传递长度参数,或用结构体封装 { char *data; size_t len; }。

字符串字面量的 sizeof 与 strlen

sizeof("hello")   // 6(5 字符 + '\0')
strlen("hello")   // 5
sizeof("")        // 1(仅 '\0')
strlen("")        // 0

实战决策指南:何时用哪个?

场景推荐理由
获取字符串逻辑长度(如截取、拼接、校验)strlen()语义精确,不含终止符
分配内存存储字符串副本strlen(s) + 1含终止符
用 memcpy/memmove 拷贝字符串strlen(src) + 1拷贝含终止符的完整内容
获取数组/结构体/基本类型占用字节sizeof编译期常量,零开销
计算结构体数组元素个数sizeof(arr)/sizeof(arr[0])仅对数组对象有效,指针无效
格式化输出大小%zu 对应 size_t跨平台可移植

进阶:嵌入空字符的字符串

C 字符串约定以首个 '\0' 为结束。若数据本身包含 '\0'(如二进制协议、UTF-16),不能用 strlen,必须显式维护长度字段(struct { void *data; size_t len; }),并用 memcmp/memcpy 等内存函数处理。

性能考量

跨平台注意:size_t 打印格式

// 正确:C99 标准
printf("len = %zu\n", strlen(s));
printf("size = %zu\n", sizeof(arr));

// 旧标准兼容(不推荐)
printf("len = %lu\n", (unsigned long)strlen(s));

总结

C语言

  1. 钎焊与软焊关键差异全解析
  2. 二冲程与四冲程发动机核心区别深度解析
  3. 链传动与齿轮传动:全面对比分析
  4. 直流与交流电机核心差异与选型指南
  5. 石棉与玻璃纤维:关键差异、用途与安全考量
  6. C 语言结构体与联合体对比:实战指南与选择建议
  7. C# 与 C++ 深度对比:特性、性能与适用场景全景解析
  8. C 与 C++ 核心差异与选型指南
  9. C 语言与 Java 全方位对比:特性、历史与应用场景深度解析
  10. Python 与 JavaScript:核心差异、特性及选型指南
  11. Python 与 Ruby:特性、优势与适用场景全面对比
  12. Python 2 与 Python 3:关键差异与版本选择指南