首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字符串函数和内存函数的模拟实现

字符串函数和内存函数的模拟实现

作者头像
Ronin305
发布2025-12-22 13:47:07
发布2025-12-22 13:47:07
960
举报
文章被收录于专栏:我的博客我的博客

1.关于strcpy字符串函数

首先strcpy的参数是两个字符指针变量char * destination(以下简称dest)和const char * source(简称src) ,返回类型是char*;dest是目标空间,src是源字符串,strcpy是将src中的字符串拷贝到dest中

char* strcpy(char * destination, const char * source );

• Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).

• 源字符串必须以 '\0' 结束。

• 会将源字符串中的 '\0' 拷⻉到⽬标空间。

• ⽬标空间必须⾜够⼤,以确保能存放源字符串。

• ⽬标空间必须可修改。

• 学会模拟实现。

模拟实现:先将dest的初始地址存在ret变量中,便于我们后面直接返回dest的初始地址。后置++是先用后+,先将src解引用,赋值给*dest,然后src和dest向后加一,地址向后移动一个字节,进行后续字符的拷贝。

以下是代码截图和运行情况

a23eba5081ef466eb8fbaaef75e396a6.png
a23eba5081ef466eb8fbaaef75e396a6.png

 2.关于strcat字符串函数

同strcpy相似,是将src中的字符串拼接到dest后,但目标字符串中也得有\0,否则没办法知道追加从哪里开始。

模拟实现:同样是将dest的初始地址存入ret变量中,为了在dest后拼接,我们首先得让dest变量指向末尾的地址,所以我们可以采用while循环,直到遇到\0,也就是指向末尾的地址时,后续同strcpy一样,将src中的字符串拷贝到dest后面,从而实现字符串拼接。

以下是代码截图和运行情况:

c68bc5474d2d407c8dac4678f705e80b.png
c68bc5474d2d407c8dac4678f705e80b.png

 3.关于strcmp字符串函数

• 标准规定:

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0 ◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。以下是模拟实现的代码截图和运行情况

42eb872860fb4a96a50b88d31aa47f87.png
42eb872860fb4a96a50b88d31aa47f87.png

 4.关于strncpy,strncat,strncmp字符串函数

这里每一个字符串函数中都多了一个n,其实也和上面那些函数相差不大,在参数中我们就要多一个参数size_t num,strncpy是拷贝num个字符从源字符串到目标空间;strncat是将src指向字符串的前num个字符拼接到dest指向的字符串末尾,再拼接一个\0;strncmp是⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.

以下是代码实现和运行情况

ad7a97e31dcc4d98bbd5352d1018d456.png
ad7a97e31dcc4d98bbd5352d1018d456.png
c82b97a6d56b40c9a1ef7cf171090cce.png
c82b97a6d56b40c9a1ef7cf171090cce.png

 5.strstr字符串函数

 char * strstr ( const char * str1, const char * str2);

在str1中寻找str2中的字符串并返回第一次出现的位置

模拟实现如下:

efd20ba0da4447d08619e2570b3d3686.png
efd20ba0da4447d08619e2570b3d3686.png

 6,memcpy内存函数

void * memcpy ( void * destination, const void * source, size_t num );

• 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。

• 这个函数在遇到 '\0' 的时候并不会停下来。

• 如果source和destination有任何的重叠,复制的结果都是未定义的。

memcpy是拷贝内存,而不是strcpy那样拷贝字符串,这里使用void*可以接受整型也可以接受字符类型等进行内存拷贝,返回类型void*,返回的是dest目标空间的起始地址。还有这里size_t num是指所占内存的大小,单位是字节。

首先我们需要一个字节一个字节进行拷贝,而不是四个字节,这样具有灵活性,假如我们需要拷贝7个字节时,就不容易出错。所以我们要将src和dest进行强制类型转换成(char*),再进行解引用赋值,从而达到一个字节的拷贝,然后同样src和dest指针变量指向的内存地址也需要向后移动一个字节,这里同样需要强制类型转换成(char*)。

模拟实现的代码和运行情况如下:

e5eb8af5038342be8f5c51cf556f9157.png
e5eb8af5038342be8f5c51cf556f9157.png

 7.memmove内存函数

void * memmove ( void * destination, const void * source, size_t num );

• 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。

• 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理

这里我们需要注意,如果有一个整型数组

int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

memmove(arr1+2, arr1, 20);

我们要将arr1,数组名就是首元素地址,从前向后拷贝20个字节也就是5个整型元素,拷贝到arr1+2,首元素地址向后移动两个整型,也就是指向3的地址,从3开始被拷贝20个字节。arr1的地址传给src,arr1+2的地址传给dest,此时dest大于src,如果我们从前向后拷贝,当1拷到3时,3的位置就变成了1,2拷到4,4的位置就变成了2,3拷到5时,由于3的位置已经变成了1,所以3拷不到5的位置,5的位置只会被拷成1,也就是说我们要拷贝的内存会被覆盖,此时我们应该如何避免呢?我们可以从后向前拷,但当dest小于src时,从后往前拷也会被覆盖内存,此时我们可以从前往后拷贝内存,当然如果src和dest没有重叠,我们从前往后或者从后往前拷贝都行。

模拟实现:

9afe723791844956802ab20bc67ec658.png
9afe723791844956802ab20bc67ec658.png

 还有memset内存函数(用来设置内存的,将内存的值以字节为单位设置成想要的内容)和memcmp内存函数等,这里我们就不做赘述。

以上就是我的一些看法和总结!如果有不同意见或者有哪里错的,欢迎指正交流!😊😊

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档