news 2026/4/19 4:41:35

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言字符串与内存操作函数模拟实现详解

一、strstr函数模拟实现

1.1 函数功能

strstr用于在字符串str1中查找子串str2的首次出现位置:

const char* strstr(const char* str1, const char* str2); char* strstr(char* str1, const char* str2);
  • 找到则返回第一次出现的起始地址

  • 找不到则返回NULL

1.2 实现原理

场景1:简单匹配
char arr[] = "abcdefabcdef"; char* p = "cdef"; char* ret = my_strstr(arr, p); // 返回 "cdefabcdef" 的起始地址
场景2:多次匹配(复杂情况)
str1: "abbbcdef\0" str2: "bbc\0"

可能存在多次匹配尝试,需要逐字符比较

1.3 模拟实现代码

char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); const char* cur = str1; // 当前查找位置 const char* s1 = NULL; const char* s2 = NULL; while (*cur != '\0') { s1 = cur; s2 = str2; // 逐字符比较 while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) { s1++; s2++; } // 如果str2完全匹配成功 if (*s2 == '\0') { return (char*)cur; // 返回找到的位置 } cur++; // 继续下一个位置 } return NULL; // 未找到 }

二、memcpy函数模拟实现

2.1 函数功能

void* memcpy(void* destination, const void* source, size_t num);
  • 将源内存区域的num个字节拷贝到目标内存区域

  • 返回目标空间的起始地址

  • 不负责处理重叠内存的拷贝

2.2 实现原理

int arr1[] = {1,2,3,4,5,6,7,8,9,10}; int arr2[20] = {0}; my_memcpy(arr2, arr1+2, 20); // 拷贝arr1中的3,4,5,6,7

内存图示:

源地址(src): arr1+2 → 元素3的位置 目标地址(dest): arr2 → 起始位置 拷贝大小: 20字节 (5个int, 假设int为4字节)

2.3 模拟实现代码

void* my_memcpy(void* dest, const void* src, size_t num) { void* ret = dest; assert(dest && src); // 逐字节拷贝 for (size_t i = 0; i < num; i++) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } return ret; }

三、memmove函数模拟实现

3.1 函数功能

void* memmove(void* destination, const void* source, size_t num);
  • memcpy功能类似,但能够处理内存重叠的情况

  • C语言标准规定memcpy负责不重叠内存拷贝,memmove负责重叠内存拷贝

3.2 内存重叠问题

int arr1[] = {1,2,3,4,5,6,7,8,9,10}; my_memmove(arr1 + 2, arr1, 20); // 将前5个元素拷贝到从索引2开始的位置

拷贝前:

索引: 0 1 2 3 4 5 6 7 8 9 值: 1 2 3 4 5 6 7 8 9 10

错误拷贝方式(从前向后):

arr1[2] = arr1[0] → 1 arr1[3] = arr1[1] → 2 arr1[4] = arr1[2] → 1 (已经被覆盖!) arr1[5] = arr1[3] → 2 (已经被覆盖!) ...

3.3 模拟实现代码(正确处理重叠)

void* my_memmove(void* dest, const void* src, size_t num) { void* ret = dest; assert(dest && src); // 情况1:dest在src前面,或内存不重叠 → 从前向后拷贝 if (dest < src) { char* d = (char*)dest; const char* s = (const char*)src; while (num--) { *d++ = *s++; } } // 情况2:dest在src后面,有重叠风险 → 从后向前拷贝 else { char* d = (char*)dest + num - 1; // 指向目标末尾 const char* s = (const char*)src + num - 1; // 指向源末尾 while (num--) { *d-- = *s--; } } return ret; }

四、关键区别与总结

4.1 strstr vs mem系列函数

函数

操作对象

返回类型

主要用途

strstr

字符串

char*

查找子串

memcpy

内存块

void*

非重叠内存拷贝

memmove

内存块

void*

任意内存拷贝(含重叠)

4.2 memcpy vs memmove

  1. 标准规定

    • memcpy:只需实现不重叠内存拷贝

    • memmove:必须处理重叠内存拷贝

  2. 实际实现

    • 某些编译器(如VS)的memcpy也能处理重叠内存

    • 但为保证可移植性,重叠时应使用memmove

  3. 性能考虑

    • 不重叠时,两者性能相近

    • 重叠时,memmove会进行方向判断,略有开销

4.3 使用建议

  1. 查找字符串子串 → 使用strstr

  2. 拷贝不重叠的内存块 → 使用memcpy(性能可能略优)

  3. 不确定内存是否重叠 → 使用memmove(更安全)

  4. 需要自己实现时 → 参考上述代码,注意处理所有边界情况

五、完整测试示例

#include <stdio.h> #include <string.h> #include <assert.h> // 测试代码 int main() { // 1. 测试my_strstr char str[] = "abcdefabcdef"; char sub[] = "cdef"; char* result = my_strstr(str, sub); printf("strstr测试: %s\n", result ? result : "未找到"); // 2. 测试my_memcpy int arr1[10] = {1,2,3,4,5,6,7,8,9,10}; int arr2[20] = {0}; my_memcpy(arr2, arr1+2, 20); printf("memcpy测试: "); for(int i = 0; i < 5; i++) printf("%d ", arr2[i]); printf("\n"); // 3. 测试my_memmove(重叠) int arr3[] = {1,2,3,4,5,6,7,8,9,10}; my_memmove(arr3+2, arr3, 20); printf("memmove测试: "); for(int i = 0; i < 10; i++) printf("%d ", arr3[i]); printf("\n"); return 0; }

这些函数是C语言中处理字符串和内存的基础工具,理解它们的实现原理对于深入理解C语言内存管理和字符串操作至关重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 17:07:24

基于tood_x101-64x4d-dconv-c4-c5_fpn_ms-2x_coco模型的家禽种类识别系统_1

1. 基于TOOD_x101-64x4d-dconv-c4-c5_fpn_ms-2x_coco模型的家禽种类识别系统 1.1. 引言 随着现代农业的快速发展&#xff0c;家禽养殖业的规模不断扩大&#xff0c;对家禽种类识别的需求也日益增长。传统的家禽识别方法主要依靠人工经验&#xff0c;存在效率低、准确性差等问…

作者头像 李华
网站建设 2026/4/18 20:29:57

从“自发自用”到“智慧调度”:农村光伏如何高效融入微电网?

分布式光伏是点亮农村绿色发展的“第一缕光”。它利用农村丰富的屋顶、庭院、农业设施顶棚等空间&#xff0c;将阳光就地转化为电能&#xff0c;直接降低了用电成本&#xff0c;减少了碳排放。随着技术成本下降&#xff0c;农村分布式光伏安装量快速增长&#xff0c;但简单地“…

作者头像 李华
网站建设 2026/4/18 14:34:44

先正达集团在中国加速布局全球级研发中心和制造工厂 | 美通社头条

、美通社消息&#xff1a;全球领先的农业科技企业先正达集团将全球领先的植保研发中心落地上海&#xff0c;并在江苏南通同步建设高标准制剂与工程化平台。一个旨在贯通研发到应用的植保领域"中国地标"正日益清晰。今年1月&#xff0c;先正达集团全球植保中国创新中心…

作者头像 李华
网站建设 2026/4/18 20:55:48

新手做自媒体,如何在30天内建立正反馈避免放弃

当你第一次踏入自媒体的世界&#xff0c;满心憧憬地按下“发布”按钮&#xff0c;却只等来寥寥几个阅读量时&#xff0c;那种失落感足以浇灭大部分人的热情。这几乎是每位新手创作者的必经之路——在最初的30天黄金期内&#xff0c;如何建立起持续的正反馈循环&#xff0c;避免…

作者头像 李华
网站建设 2026/4/17 16:44:55

开源的自动驾驶框架

目前主流的开源自动驾驶框架&#xff0c;这类框架覆盖了从入门学习、算法研发到工程落地、实车部署的全场景&#xff0c;核心分为全栈式框架&#xff08;覆盖感知/预测/决策/规划/控制全流程&#xff0c;可直接对接实车&#xff09;和模块化框架&#xff08;聚焦单一环节&#…

作者头像 李华
网站建设 2026/4/18 8:35:56

STM32F407通过UART读取JY-901加速度数据方案

一、硬件连接与配置 1. 引脚连接 JY-901与STM32F407的UART接口连接如下&#xff08;以USART2为例&#xff09;&#xff1a;JY-901引脚STM32引脚功能TXPA3JY-901发送端RXPA2JY-901接收端VCC3.3V电源供电GNDGND共地2. 波特率设置 JY-901默认波特率为9600bps&#xff0c;需在STM32…

作者头像 李华