strlen 是 C 语言标准库 <string.h> 中一个非常重要且常用的函数。

(图片来源网络,侵删)
strlen 是什么?
strlen (string length) 函数用于计算一个以 空字符 (\0) 结尾的字符串的长度。
关键点:
- 功能: 计算字符串长度。
- 返回值:
size_t类型(一个无符号整数类型),表示字符串中字符的数量(不包括结尾的空字符\0)。 - 参数:
const char *str,一个指向字符串首字符的常量指针,你不能通过这个指针修改字符串内容。 - 头文件: 使用
strlen必须包含<string.h>头文件。
函数原型
#include <stddef.h> // size_t 通常定义在这里,但 <string.h> 也会包含它 size_t strlen(const char *str);
工作原理
strlen 函数从传入的地址开始,逐个字符地检查内存内容,直到遇到第一个空字符 \0 为止,它会计算从起始位置到 \0 之前的所有字符的数量,并返回这个计数值。
内存示意图:

(图片来源网络,侵删)
假设一个字符串 "Hello" 在内存中是这样存储的:
| 地址 | 说明 | |
|---|---|---|
| 1000 | 'H' | 字符串开始 |
| 1001 | 'e' | |
| 1002 | 'l' | |
| 1003 | 'l' | |
| 1004 | 'o' | |
| 1005 | \0 |
字符串结束符 |
当调用 strlen("Hello") 时:
- 函数接收到的指针指向地址
1000。 - 它读取地址
1000的内容,是'H',计数器count = 1。 - 它读取地址
1001的内容,是'e',计数器count = 2。 - ...以此类推...
- 它读取地址
1004的内容,是'o',计数器count = 5。 - 它读取地址
1005的内容,是\0。 - 函数立即停止,并返回当前的计数值
5。
代码示例
下面是一个完整的 C 语言示例,展示了如何使用 strlen。
#include <stdio.h>
#include <string.h> // 必须包含这个头文件才能使用 strlen
int main() {
char str1[] = "Hello, World!";
char str2[] = "C Programming";
char str3[] = ""; // 空字符串
// 计算 str1 的长度
size_t len1 = strlen(str1);
printf("The length of \"%s\" is: %zu\n", str1, len1); // 输出: The length of "Hello, World!" is: 13
// 计算 str2 的长度
size_t len2 = strlen(str2);
printf("The length of \"%s\" is: %zu\n", str2, len2); // 输出: The length of "C Programming" is: 13
// 计算 str3 的长度
size_t len3 = strlen(str3);
printf("The length of \"%s\" is: %zu\n", str3, len3); // 输出: The length of "" is: 0
return 0;
}
重要注意事项(陷阱)
陷阱 1:strlen 不会检查缓冲区边界
strlen 会一直向后查找 \0,如果字符串没有正确地以 \0 它就会继续读取内存中的其他内容,直到偶然遇到一个值为 0 的字节,或者访问到非法内存导致程序崩溃(段错误)。

(图片来源网络,侵删)
错误示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[5] = "Hello"; // 注意:这个字符串没有空间存放 '\0'
// 内存中可能只有 "Hello",没有结束符。
// strlen 会从 'H' 开始找,找不到 '\0',会一直往后读,
// 导致未定义行为,很可能程序崩溃或得到一个完全错误的巨大数字。
size_t len = strlen(str);
printf("Length: %zu\n", len); // 危险!输出不可预测。
return 0;
}
正确做法: 确保字符串数组有足够的空间存放所有字符加上一个结尾的 \0。
char str[6] = "Hello"; // 正确,5个字符 + 1个 '\0'
陷阱 2:返回值是 size_t(无符号整数)
strlen 返回的是 size_t,这是一个无符号类型,这在与其他有符号整数(如 int)进行比较或计算时,可能会引发意想不到的问题。
经典错误示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "A very long string...";
if (strlen(str) - 100 < 0) {
// 这个判断可能永远为 false!
// 因为 strlen(str) 返回一个无符号数,200。
// 200 - 100 = 100,这是一个无符号数,不可能小于 0。
printf("The string is short.\n");
} else {
printf("The string is long.\n"); // 这里的代码总是会被执行
}
return 0;
}
正确做法: 在进行比较或可能产生负数的运算时,将 size_t 类型的结果转换为 int 或 ssize_t(有符号的 size_t)。
if ((int)strlen(str) - 100 < 0) {
// 现在是正确的比较
printf("The string is short.\n");
}
如何手动实现 strlen?
理解 strlen 的工作原理后,我们可以自己动手写一个简单的版本。
#include <stdio.h>
// 自定义的 my_strlen 函数
size_t my_strlen(const char *str) {
size_t length = 0;
// 循环,直到遇到字符串结束符 '\0'
while (str[length] != '\0') {
length++;
}
return length;
}
int main() {
char my_str[] = "Test my_strlen";
printf("Length using my_strlen: %zu\n", my_strlen(my_str)); // 输出: 16
return 0;
}
这个版本虽然直观,但效率不是最高的,更高效的版本通常使用指针运算:
size_t my_strlen_ptr(const char *str) {
const char *p = str;
// 移动指针 p,直到它指向 '\0'
while (*p != '\0') {
p++;
}
// 指针相减得到它们之间的元素个数
return p - str;
}
| 特性 | 描述 |
|---|---|
| 函数名 | strlen |
| 头文件 | <string.h> |
| 功能 | 计算以 \0 结尾的字符串的长度。 |
| 返回值 | size_t 类型,表示字符数量(不含 \0)。 |
| 关键陷阱 | 不检查边界:必须确保字符串以 \0 返回值无符号: size_t 在与有符号数运算时要小心。 |
strlen 是 C 语言字符串处理的基础,正确理解和使用它对于编写健壮的 C 程序至关重要。
