手动实现<string.h>中的各个函数
本文尚未完成…
本文将通过手动实现C标准库 <string.h> 中的常用函数,深入理解字符串处理的底层原理。
当然,我们只是简单实现。glibc中的工业级实现肯定要复杂得多。
计算字符串长度
介绍 - strlen
在标准库<string.h>中,strlen()函数可以用于计算字符串长度(不包括结尾的\0)。
标准库原型如下:
1
size_t strlen(const char *str);手动实现 strlen
方法一: 计数器遍历
1
2
3
4
5
6
7
8
9
10
11
#include <stddef.h>
size_t my_strlen(const char *str) {
size_t len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}方法二: 指针减法(高效)
1
2
3
4
5
6
7
8
9
10
11
size_t my_strlen2(const char *str) {
const char *start = str;
// 移动指针到字符串末尾
while (*str) {
str++;
}
// 指针相减得到元素个数
return str - start;
}方法三:递归实现(不推荐,仅作演示)
1
2
3
4
5
6
size_t my_strlen3(const char *str) {
if (*str == '\0') {
return 0;
}
return 1 + my_strlen3(str + 1);
}方法四:性能优化版本(一次处理4字节)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 使用位运算的优化版本
size_t my_strlen_fast(const char *str) {
const char *ptr = str;
// 对齐到4字节边界
while (((uintptr_t)ptr & 3) && *ptr) {
ptr++;
}
if (*ptr == '\0') return ptr - str;
// 一次检查4字节
const uint32_t *word_ptr = (const uint32_t *)ptr;
uint32_t word;
while (1) {
word = *word_ptr++;
if ((word & 0xFF000000) == 0 ||
(word & 0x00FF0000) == 0 ||
(word & 0x0000FF00) == 0 ||
(word & 0x000000FF) == 0) {
break;
}
}
// 找到具体位置
ptr = (const char *)(word_ptr - 1);
while (*ptr) ptr++;
return ptr - str;
}性能对比
| 实现方式 | 时间复杂度 | 适用场景 |
|---|---|---|
| 计数器遍历 | O(n) | 通用,简单明了 |
| 指针减法 | O(n) | 略微高效 |
| 递归实现 | O(n),但栈溢出风险 | 仅用于理解递归 |
| 一次4字节 | O(n/4) | 长字符串优化 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GuYang17的小站!
评论