本文尚未完成…

本文将通过手动实现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) 长字符串优化