C语言字符串与内存库函数模拟实现详解
掌握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语言指针与底层优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













