目录
引言:
在上一篇文章中,我们已经讲解了如何使用对字符串操作的库函数,已经如何去模拟实现那些函数,那么,如果我们想要进行拷贝或比较操作的是别的类型的数组呢,那么,这个时候就要用到我们C语言库中的内存函数了
那么,话不多说,接下来我们进入内存函数详解正篇------------------>

1.memcpy函数
cpp
void * memcpy ( void * destination, const void * source, size_t num );
memcpy和strcnpy其实是大差不大的,strncpy的功能是将源字符串的num个字母拷贝到目标字符串中
memcpy就是将原数组中的num个字节拷贝到目标数组中
因为字符串也是数组,所以memcpy会了后,用memcpy替代strncpy来拷贝字符串也是可以的
1.1.memcpy函数的使用
特别注意:这个函数在遇到\0的时候并不会停下来
如果原内存和目标空间有重叠的话,复制的结果就是未定义的(为什么会未定义可以通过看模拟实现知道缘由)如果涉及空间重叠部分的拷贝,就要使用memmove函数
附:VS的memcpy函数是可以实现重叠空间的拷贝的,其实原理就是将memcpy优化的跟memmove差不多
memcpy函数拷贝结束后返回的值是目标空间的首地址
那么我们来举例如何使用memcpy,代码如下
cpp
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
上述代码中源空间就是arr1,目标空间就是arr2,就是讲arr1中的20个字节全部复制给arr2,注意是字节,所以arr2拷贝完是1,2,3,4,5
1.2.memcpy函数的模拟实现
cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* p1,void* p2,int cnt)
{
assert(p1&&p2);
char* P1 = (char*)p1;
char* P2 = (char*)p2;
while(cnt--)
{
*P1++ = *P2++;
}
return p1;
}
int main()
{
long long a[10] = {0};
long long b[10] = {1,2,3,4,5};
my_memcpy(a,b,4*sizeof(b[0]));
for(int i = 0;i<10;i++)
{
printf("%lld", a[i]);
}
return 0;
}
2.memmove函数
cpp
void * memmove ( void * destination, const void * source, size_t num );
2.1.memmove函数的使用
memmove函数跟memcpy函数实现的功能是一样的,就是多了可以有重复空间的拷贝,返回的类型和返回的是什么跟memcpy是一样的,参数使用也是跟memcpy一样的,所以使用就不讲了,直接就讲模拟实现啦
2.2.memmove函数的模拟实现
cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* p1,void* p2,int cnt)
{
assert(p1&&p2);
char* P1 = (char*)p1;
char* P2 = (char*)p2;
if(P1>=P2)
{
while(cnt--)
*(P1+cnt)=*(P2+cnt);
}
else
{
while(cnt--)
*P1++ = *P2++;
}
return p1;
}
int main()
{
long long a[10] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(a,a+1,5*sizeof(a[0]));
for(int i = 0;i<10;i++)
{
printf("%lld", a[i]);
}
return 0;
}
3.memset函数
cpp
void * memset ( void * ptr, int value, size_t num );
这个函数是用来设置内存的,将内存中的值以字节为单位设置成想要的内容
这个函数的返回值就是目标空间的首地址
3.1.memset函数的使用
这里就直接举个例子,代码如下
cpp
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
这个就是将从str这个地址开始及往后的6个字节全都设成x,因为是char类型,所以改一个字节就是改一个字符,所以改完后输出结果就是如下了
xxxxxxworld
但我们在平常使用的时候,应该这个是你们见的最多的,代码如下
cpp
int a[10];
int b[10];
memset(a,0,sizeof(a));
memset(b,0x3f,sizeof(b));
一个是将a数组的所有字节都改为0,那么就是将数组清0
一个是将b数组的所有字节都改为3f,那么一个元素的大小就是0x3f3f3f3f,也相当于是把数组 元素重置为无限大
那么,使用讲完了,我们来讲讲如何模拟实现
3.2.memset函数的模拟实现
cpp
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memset(void* p1,int x,int cnt)
{
for(int i = 0;i<cnt;i++)
{
*((char*)p1+i)=x;
}
return p1;
}
4.memcmp函数
cpp
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
这个函数其实跟strncmp函数差不多,就是比较源空间和目标空间前num个字节,比较原理就跟strncmp函数是一样的,这里就不过多赘述了
4.1.memcmp函数的使用
cpp
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}
4.2.memcmp函数的模拟实现
cpp
int mt_memcmp(const void* p1,const void* p2,int cnt)
{
char* P1 = (char*)p1;
char* P2 = (char*)p2;
while(cnt--)
{
if(*P1>*P2)
return 1;
if(*P1++ <*P2++)
return -1;
}
return 0;
}
结语:
希望以上内容对你有所帮助,感谢观看,若觉得写的还可以,可以分享给朋友一起来看哦,毕竟一起进步更有动力嘛
