跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 工具系统 > 防关联工具 > C语言:内存函数

C语言:内存函数

时间:2024-04-28 09:10:29 来源:网络cs 作者:亙句 栏目:防关联工具 阅读:

标签: 函数  语言 

前言

本篇博文是关于C语言中内存函数的相关内容、使用及其模拟实现,欢迎各位友友三连学习哦!

一、memcpy使用和模拟实现

1. memcpy函数的使用

mem--memory--记忆,(在计算机中)内存

与strcpy相比,memcpy是针对内存块进行的拷贝 

1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置(右边的数据拷贝到左边来)

2. 函数遇到'\0'不会停下来

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

4. 返回值:memcpy拷贝结束后,返回的是目标空间的起始地址,而且是void*类型(实现各种类型数据的拷贝)

5. 使用该函数,需要引用头文件:string.h

2. memcpy函数的模拟实现

 ·使用void*类型的指针,是为了能够进行各种类型数据的拷贝

·将void*类型的指针强制类型转换成char*类型,一次解引用访问一个字节;但是转换成int*类型就会不方便:若拷贝的数据是7(奇数)个字节,则int*类型的指针解引用访问4个字节,不能刚好记就拷贝完所有数据。

void* my_memcpy(void* dest, const void* src, size_t num)//void*类型的指针:可以用来接收各种类型的地址{void* ret = dest;//备份dest的初始值int i = 0;//指针解引用:assert断言assert(src && dest);while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;//也可以写成:(char*)dest++;//            (char*)src++;//dest和 src不再指向初始地址}//返回目标空间的起始地址return ret;}int main(){int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 20);//5个字节(以字节为单位)int i = 0;for (i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;}

那针对上面的代码,能否实现将arr1中的1、2、3、4、5拷贝到arr1中的4、5、6、7、8中呢?

void* my_memcpy(void* dest,const void* src,size_t num)//void*类型的指针:可以用来接收各种类型的地址{void* ret = dest;//备份dest的初始值int i = 0;//指针解引用:assert断言assert(src && dest);while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;//也可以写成:(char*)dest++;                       //            (char*)src++;}//返回目标空间的起始地址return ret;}//1 2 3 4 5 (源空间)拷贝放在 3 4 5 6 7(目标空间)int main(){//strcpy--字符串的拷贝int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//一边拷贝,源空间一边被改my_memcpy(arr1+2, arr1, 20);//memcpy(arr1 + 2, arr1, 20);//结果不一样:因为memcpy完成不重叠的拷贝int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;}

 运行结果:

对该运行结果的分析过程:

 

memcpy函数的运行结果:

可以发现两个结果不一样,因此,记住,不能期望memcpy函数能够实现重叠内存块的拷贝。

既然这样,那内存块重叠的拷贝应该如何实现呢?这就引出了memmove函数。

二、 memmove函数的使用和模拟实现

2.1 memmove函数的使用 

memmove函数的使用方式几乎和memcpy函数一样。

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

运行结果:

2.2 memmove函数的模拟实现

如果我们想将一个数组{1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10}中的 1,2 ,3,4,5拷贝到该数组中的3,4,5,6,7的位置,应该如何进行拷贝呢?,根据下图,我们的预期结果就是:输出1 2 1 2 3 4 5 8 9 10.

在前面的一张图中,我们就分析了一种办法,就是将需要拷贝的元素一个一个地从前向后拷贝,但是这种办法不能达到我们预期想要的结果(1 2 1 2 1 2 1 8 9 10)(也就是该方法从前向后仅适用于部分情况,如:该数组的3 4 5 6 7拷贝到1 2 3 4 5中去,就可以从前向后拷贝)。还有两种办法:法一:添加一个备份数组,在备份数组中完成拷贝后将改数字的数据放回源数组。

但是该方法缺点就是:添加了一个备份数组,浪费了空间资源,所以选择方法二。

法二:将需要进行拷贝的数据进行倒着拷贝,分析过程如下图:

 这样,就不会出现之前的数据一边拷贝一边被修改的情况了。

但是,我们应该如何选择数据是从前向后拷贝还是从后向前拷贝呢?

选择方法一区分就比较简单。对于34567拷贝在12345的memmove函数模拟实现的代码如下:得到的就是预期的结果

// //memmove函数拷贝完成之后会返回目标空间的起始地址void* my_memmove(void* dest, const void* src, size_t num) {assert(dest && src);void* ret = dest;if (dest < src){//前-->后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{//后-->前while (num--){*((char*)dest + num)= *((char*)src + num);}}return ret;}int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 5 * sizeof(int));int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;}

三、memset函数的使用和模拟实现

 3.1 memset函数的使用

1. ptr:指向需要被填充的内存块;

2. value:需要设置的值;

3. num:字节个数(以字节为单位,不能以元素类型为单位进行设置);

4. 使用该函数需要引用头文件string.h 

4. 作用:以字节为单位,把ptr指向的位置的数据设置成num个value。例如:

注意:memset是以字节为单位对值进行设置的,而不是以元素为单位设置的(设置的不是元素)

对于下面的代码:

#include <string.h>#include <stdio.h>int main(){int arr[5] = { 0 };//memset(arr, 1, 20);//20个字节(以字节为单位):从arr数组的第一个元素开始,往后将每一个元素设置为1,一共设置20个字节for (int i = 0; i < 5; i++){//打印这5个元素printf("%d ", arr[i]);}return 0;}

我么预期结果是输出:1 1 1 1 1,但是现在输出的却是:

利用调试来分析此结果出现的原因:

十六进制的1010101转换成二进制,就是16843009,所以输出了5个16843009。

如果是改成0的话,就可以使用此方法,使得每一个字节都变成0,结果就是0

四、memcmp函数的使用及模拟实现

1. 从ptr1和ptr2指针指向的位置开始,向后访问num个字节的内容,进行比较; 

2. 针对内存块的比较

3. 返回值:

 例如:

#include <string.h>#include <stdio.h>int main(){int arr1[] = { 1,2,3,4,5,6,7 };int arr2[] = { 1,2,3,4,8,8,8 };int ret = memcmp(arr1, arr2, 16);printf("%d\n", ret);return 0;}

 进行一个字节一个字节的比较,比了 16个字节,结果还是一样大,所以返回0。


以上就是内存函数相关的全部分享啦!友友的支持会是我前进的动力哦!

本文链接:https://www.kjpai.cn/news/2024-04-28/163126.html,文章来源:网络cs,作者:亙句,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论