内存函数的使用和模拟实现
创始人
2025-05-28 20:50:15

前面我们学习了字符串函数,http://t.csdn.cn/j3tSg,看一下自己有没有忘记呢,复习一下吧。

那么今天我要分享的是内存函数,为什么我会给大家分享这个呢?或者说,内存函数的作用是什么呢?有了字符函数就行了,为什么还会有内存函数呢?那么我们就先来看看字符函数和字符串函数的局限性。

字符函数和字符串函数,看见这个名字我们应该就可以知道这个函数的操作对象是什么了,没错,字符函数和字符串函数是操作字符和字符串的,但是平常生活中我们遇到的可不止有字符串,所以这时候就出现了内存函数,它的好处是:可以操作任意类型的数据,这样就极大的方便了我们了我们的生活。接下来我们就来看看这些内存函数是如何使用以及自己来模拟实现它。

目录

memcmp

模拟实现memcmp

memcpy

模拟实现memcpy 

memmove

模拟实现memmove

 小结:


memcmp

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

这个函数的意思是将ptr1中num个字节与ptr2中num个字节进行比较,ptr1大于ptr2则返回大于0的数,相等返回0,小于则返回一个小于0的数。我们先来使用库函数来看看memcmp是怎样工作的吧。

#include
#includeint main()
{int arr1[] = { 1,2,3,4,5,6 };int arr2[] = { 1,2,3,4,6,5 };int ret = memcmp(arr1, arr2, 16);printf("%d\n",ret);return 0;
}

#include
#includeint main()
{int arr1[] = { 1,2,3,4,5,6 };int arr2[] = { 1,2,3,4,6,5 };int ret = memcmp(arr1, arr2, 20);printf("%d\n",ret);return 0;
}

 

 知道库函数memcmp是怎么工作的之后,我们就来自己模拟实现memcmp

模拟实现memcmp

#include//这里参数的类型为void,能接受任何类型的数据
int my_memcmp(const void* arr1, const void* arr2, size_t num)
{//因为不能对void类型的数据直接解引用,所以这里得强制类型转化为//char*类型,然后一个字节一个字节的操作。char* str1 = (char*)arr1; char* str2 = (char*)arr2;while (num--){if (*str1 != *str2){return *str1 - *str2;}str1++;str2++;}return 0;
}int main()
{int arr1[] = { 1,2,3,4,5,6 };int arr2[] = { 1,2,3,4,6,5 };int ret = my_memcmp(arr1, arr2, 20);printf("%d\n", ret);return 0;
}

memcpy

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

此函数的目的是将从source开始的num个字节的数据拷贝到destination中。先来使用库函数来实现这个功能。

#include
#includeint main()
{int arr1[] = { 1,2,3,4,5,6,5,7,8 };int arr2[10] = { 0 };memcpy(arr2, arr1, 6 * sizeof(int));for (int i = 0; i < 6; i++){printf("%d ", arr2[i]);}return 0;
}

然后就是我们自己来模拟实现memcpy

模拟实现memcpy 

#includevoid* my_memcpy(void* destination, void* source, size_t num)
{char* str1 = (char*)destination;char* str2 = (char*)source;while (num--){*str1 = *str2;str1++;str2++;}return destination;
}int main()
{int arr1[] = { 1,2,3,4,5,6,7,8 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, 6 * sizeof(int));for (int i = 0; i < 6; i++){printf("%d ", arr2[i]);}return 0;
}

我们这里看到的是两块没有重叠的部分的拷贝,那么当我们的destination和source有重叠的时候这个memcpy能不能实现呢?我们来看看 

#includevoid* my_memcpy(void* destination, void* source, size_t num)
{char* str1 = (char*)destination;char* str2 = (char*)source;while (num--){*str1 = *str2;str1++;str2++;}return destination;
}int main()
{int arr1[] = { 1,2,3,4,5,6,7,8 };my_memcpy(arr1+2, arr1, 4 * sizeof(int));for (int i = 0; i < 8; i++){printf("%d ", arr1[i]);}return 0;
}

我们想要得到1,2,1,2,3,4,7,8的结果,可是呢?我们看看运行结果

这里并没有得到我们期待的结果,所以memcpy并不能处理有重叠的情况,那么接下来我要介绍的就可以处理有重叠情况的拷贝了。 

memmove

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

这个函数的意思是,从source开始的num个字节移动到从destination开始的num个字节。

还是先来看看库函数是怎样使用的:

#include
#includeint main()
{int arr[6] = { 1,2,3,4,5,6 };memmove(arr, arr + 2, 4 * sizeof(int));for (int i = 0; i < 6; i++){printf("%d ", arr[i]);}return 0;
}

当我们来自己实现的时候,我们要想想怎么做?是不是每一次都是从左往右来实现呢?我们来看一个例子:先给一个1-6的数组,然后我们的目的就是想要把1,2,3,4移动到3,4,5,6的位置,最后得到1,2,1,2,3,4,我们就按照从左往右的顺序来移动,看看结果会是怎么样的。

 我们先移动1,2

此时原来的3,4的位置已经被改为了1,2,然后我们来继续移动

 

结果就是这样的,并不能得到我们想要的结果,那么这题应该怎么做呢?我们换个思路,从右往左移动,

 

那么我们就需要讨论,当需要移动的值跟destination以及后面的num个字节有重叠部分时,当destination>source时,就从右往左移动,相反就从左往右移动 ,当他们没有重叠部分就两种情况都可以,所以为了方便我们就将没有重叠的情况也从右往左移动。

模拟实现memmove

#include
#includevoid my_memmove(void* destination, void* source, size_t num)
{assert(destination && source);char* str1 = (char*)destination;char* str2 = (char*)source;if (str1 > str2 || (str1

再来看看另外一种情况是否也能得到结果。

#include
#includevoid my_memmove(void* destination, void* source, size_t num)
{assert(destination && source);char* str1 = (char*)destination;char* str2 = (char*)source;if (str1 > str2 || (str1

 小结:

那么这些就是我学到的关于内存函数的内容了,感谢大家的观看,如遇错误的地方,欢迎大家指点,我们一起进步。

相关内容

热门资讯

联动云租一天多少钱(联动云租一... 本篇文章极速百科给大家谈谈联动云租一天多少钱,以及联动云租一天怎么划算对应的知识点,希望对各位有所帮...
飞机托运收费(飞机托运收费多少... 本篇文章极速百科给大家谈谈飞机托运收费,以及飞机托运收费多少钱一公斤对应的知识点,希望对各位有所帮助...
挡泥板(挡泥板是什么意思) 挡... 本篇文章极速百科给大家谈谈挡泥板,以及挡泥板是什么意思对应的知识点,希望对各位有所帮助,不要忘了收藏...
滴滴专车官网(滴滴专车司机网站... 今天给各位分享滴滴专车官网的知识,其中也会对滴滴专车司机网站进行解释,如果能碰巧解决你现在面临的问题...
路特斯跑车(路特斯跑车多少钱一... 今天给各位分享路特斯跑车的知识,其中也会对路特斯跑车多少钱一辆2023款进行解释,如果能碰巧解决你现...
丰田致享新车报价(丰田致享20... 今天给各位分享丰田致享新车报价的知识,其中也会对丰田致享2021款报价进行解释,如果能碰巧解决你现在...
聊城到潍坊的汽车(聊城到潍坊的... 本篇文章极速百科给大家谈谈聊城到潍坊的汽车,以及聊城到潍坊的汽车票价多少对应的知识点,希望对各位有所...
没有身份证怎么买票(没有身份证... 今天给各位分享没有身份证怎么买票的知识,其中也会对没有身份证怎么买票进行解释,如果能碰巧解决你现在面...
2018科目三灯光详细表(20... 本篇文章极速百科给大家谈谈2018科目三灯光详细表,以及2018科目三最新模拟灯光考试20组不重复完...
五菱之光v(五菱之光v和五菱之... 今天给各位分享五菱之光v的知识,其中也会对五菱之光v和五菱之光有什么区别进行解释,如果能碰巧解决你现...
摩托车怠速(摩托车怠速多少转正... 今天给各位分享摩托车怠速的知识,其中也会对摩托车怠速多少转正常进行解释,如果能碰巧解决你现在面临的问...
武汉到西安(武汉到西安火车时刻... 今天给各位分享武汉到西安的知识,其中也会对武汉到西安火车时刻表查询进行解释,如果能碰巧解决你现在面临...
五菱之光v图片(五菱之光v新车... 今天给各位分享五菱之光v图片的知识,其中也会对五菱之光v新车报价进行解释,如果能碰巧解决你现在面临的...
郑州到重庆火车(郑州到重庆火车... 本篇文章极速百科给大家谈谈郑州到重庆火车,以及郑州到重庆火车多少钱一张对应的知识点,希望对各位有所帮...
学生证优惠区间(学生证优惠区间... 今天给各位分享学生证优惠区间的知识,其中也会对学生证优惠区间没有盖章进行解释,如果能碰巧解决你现在面...
武汉到合肥(武汉到合肥多少公里... 今天给各位分享武汉到合肥的知识,其中也会对武汉到合肥多少公里进行解释,如果能碰巧解决你现在面临的问题...
软座座位分布图(k8412软座... 本篇文章极速百科给大家谈谈软座座位分布图,以及k8412软座座位分布图对应的知识点,希望对各位有所帮...
长安逸动dt(长安逸动dt空调... 本篇文章极速百科给大家谈谈长安逸动dt,以及长安逸动dt空调滤芯拆卸教程对应的知识点,希望对各位有所...
西安到达州(西安到达州火车时刻... 本篇文章极速百科给大家谈谈西安到达州,以及西安到达州火车时刻表查询对应的知识点,希望对各位有所帮助,...
野马蝰蛇(野马蝰蛇gt500图... 本篇文章极速百科给大家谈谈野马蝰蛇,以及野马蝰蛇gt500图片对应的知识点,希望对各位有所帮助,不要...
高速obu是什么意思(收费站o... 今天给各位分享高速obu是什么意思的知识,其中也会对收费站obu是什么意思进行解释,如果能碰巧解决你...
西安北站在哪(西安北站在哪进站... 今天给各位分享西安北站在哪的知识,其中也会对西安北站在哪进站进行解释,如果能碰巧解决你现在面临的问题...
汽车搭电一次多少钱(汽车搭电大... 今天给各位分享汽车搭电一次多少钱的知识,其中也会对汽车搭电大概多少钱进行解释,如果能碰巧解决你现在面...
宝马跑车敞篷价格(宝马跑车敞篷... 本篇文章极速百科给大家谈谈宝马跑车敞篷价格,以及宝马跑车敞篷价格图片对应的知识点,希望对各位有所帮助...
cbr650r(cbr650r... 本篇文章极速百科给大家谈谈cbr650r,以及cbr650r座高对应的知识点,希望对各位有所帮助,不...
在哪买机票最便宜(在哪买机票最... 今天给各位分享在哪买机票最便宜的知识,其中也会对在哪买机票最便宜票进行解释,如果能碰巧解决你现在面临...
etc办理点(etc办理点节假... 今天给各位分享etc办理点的知识,其中也会对etc办理点节假日休息吗进行解释,如果能碰巧解决你现在面...
宝马1181报价及图片(宝马1... 今天给各位分享宝马1181报价及图片的知识,其中也会对宝马1181报价及图片及价格进行解释,如果能碰...
限行处罚扣分吗(限行被扣分吗)... 本篇文章极速百科给大家谈谈限行处罚扣分吗,以及限行被扣分吗对应的知识点,希望对各位有所帮助,不要忘了...
车车(车车车念什么) 车车 车... 今天给各位分享车车的知识,其中也会对车车车念什么进行解释,如果能碰巧解决你现在面临的问题,别忘了关注...