C语言字符串与内存库函数模拟实现详解

阿麦
阿麦
发布时间:2026-10-15 | 1人浏览过
原创

掌握C语言标准库函数的底层实现是提升编程能力的关键。本文详细讲解如何从零模拟实现 strlen、strcmp、strcpy、strcat 以及处理内存重叠的 memcpy 和 memmove。通过分析指针移动、空字符 \0 的处理机制以及内存覆盖场景,提供完整的 C/C++ 代码示例,帮助开发者深入理解字符串与内存操作的本质。

字符串检验类函数

第1步:实现 strlen 计算字符串长度

功能目标:返回空终止字符串的长度(不包含末尾的 '\0')。

核心逻辑:初始化计数器为 0,从字符串首地址开始遍历,每访问一个非 '\0' 字符则计数加 1 并移动指针,直到遇到 '\0' 为止。

size_t my_strlen(const char* str) {
    size_t cnt = 0;
    while (*str != '\0') {
        ++str;
        ++cnt;
    }
    return cnt;
}

第2步:实现 strcmp 进行字典序比较

功能目标:按字节比较两个字符串。相等返回 0;lhs 大于 rhs 返回正数;lhs 小于 rhs 返回负数。

核心逻辑:同时遍历两个字符串,计算对应字符 ASCII 码之差。若差值为 0 且未到达结尾,继续遍历;否则返回差值。注意 '\0' 的 ASCII 最小,能正确处理一个串结束而另一个未结束的情况。

int my_strcmp(const char* lhs, const char* rhs) {
    int res = 0;
    // 当两字符相等且均未结束时循环
    while ((res = *lhs - *rhs) == 0 && *lhs != '\0' && *rhs != '\0') {
        ++lhs;
        ++rhs;
    }
    return res;
}

第3步:实现 strstr 查找子串

功能目标:在主串中寻找子串首次出现的位置。

核心逻辑:暴力匹配法。外层循环遍历主串每个字符作为起始点;内层循环尝试匹配子串。若子串匹配成功(即内层走到 '\0'),返回当前主串位置指针。

char* my_strstr(const char* str, const char* substr) {
    if (substr == NULL) {
        return (char*)str;
    }

    while (*str != '\0') {
        const char* backStr = str;
        const char* backSub = substr;
        // 尝试匹配子串
        while (*backStr != '\0' && *backSub != '\0' && *backStr == *backSub) {
            ++backStr;
            ++backSub;
        }
        // 子串完全匹配
        if (*backSub == '\0') {
            return (char*)str;
        }
        ++str;
    }
    return NULL;
}

字符串操作类函数

第4步:实现 strcpy 字符串复制

功能目标:将 src 字符串内容复制到 dest。

风险提醒:dest 必须有足够空间存放 src 及其 '\0',否则会导致缓冲区溢出。如果 src 和 dest 区域重叠,行为未定义。

核心逻辑:先保存 dest 初始地址用于返回值,然后逐个字符复制直到包含 '\0'。

char* my_strcpy(char* dest, const char* src) {
    char* res = dest;
    while ((*dest++ = *src++) != '\0');
    return res;
}

第5步:实现 strcat 字符串追加

功能目标:将 src 追加到 dest 末尾。

核心逻辑:首先找到 dest 末尾的 '\0' 位置,然后从该位置开始,将 src 的内容逐个拷贝过去,直到覆盖掉 dest 原有的 '\0' 并将 src 的 '\0' 也拷贝完毕。

char* my_strcat(char* dest, const char* src) {
    char* res = dest;
    // 寻找 dest 结尾
    while (*dest != '\0') {
        dest++;
    }
    // 追加 src
    while ((*dest++ = *src++) != '\0');
    return res;
}

内存操作类函数

第6步:实现 memcpy 无重叠内存复制

功能目标:复制指定字节数 count 个字节。

说明:memcpy 假设源和目标内存不重叠,因此直接正向复制即可,速度最快。

核心逻辑:使用 void* 接收通用指针,每次复制一个 char 大小的字节并递减计数器。

void* my_memcpy(void* dest, const void* src, size_t count) {
    void* res = dest;
    while (count--) {
        *(char*)dest = *(char*)src;
        dest = (char*)dest + 1;
        src = (char*)src + 1;
    }
    return res;
}

第7步:实现 memmove 处理重叠内存复制

功能目标:安全地复制可能重叠的内存区域。

核心逻辑:

  • 若 dest < src(目标地址在源地址之前):正向复制,不会产生冲突。
  • 若 dest >= src(目标地址在源地址之后):反向复制(从后往前),避免前面复制覆盖后面待复制的数据。

图示1:dest 在 src 前,采用正向复制

图示2 & 3:dest 在 src 后,存在重叠时采用反向复制

void* my_memmove(void* dest, const void* src, size_t count) {
    void* res = dest;
    if (dest < src) {
        // 正向复制:目标在前,源在后
        while (count--) {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    } else {
        // 反向复制:目标在后,源在前,防止重叠覆盖
        while (count--) {
            *((char*)dest + count) = *((char*)src + count);
        }
    }
    return res;
}

以上就是C语言模拟实现字符串与内存库函数的详细内容,更多关于C语言指针与底层优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表