1.memcpy

它可以理解为memory + copy的组合,memory有记忆的意思,这里指的是内存,copy是拷贝,这个函数是针对内存块进行拷贝的

函数原型

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

从source位置开始,向后num个数据拷贝到destination中,它与字符串的strcopy类似,但是遇到'\0'不会停下来,同时,两者的内存不能重叠

我们先来写代码使用一下爱这个函数吧

int main()

{

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

int arr2[20] = { 0 };

my_memcpy(arr2, arr1, 20); //字节的长度

int i = 0;

for (i = 0; i < 20; i++)

{

printf("%d ", arr2[i]);

}

return 0;

}

在这个代码中,我们将arr1的内容拷贝到了arr2中,拷贝了20个字节,也就是5个int类型的数字,一定要注意是字节的拷贝,这是运行结果

现在,我们来模拟实现这个函数吧

void* my_memcpy(void* dest, void* src, size_t num)

{

int i = 0;

void* ret = dest;

assert(dest && src);

/*for (i = 0; i < num; i++)

{

*((char*)dest + i) = *((char*)src + i);

}*/

while (num--)

{

*(char*)dest = *(char*)src;

dest = (char*)dest + 1;

src = (char*)src + 1;

}

return ret;

}

那如果我们想实现在一个数组内进行操作,比如我想操作arr1数组,把第二个数字开始更改,进行拷贝,如果我们写出如下的代码,可能运行结果与我们考虑的就不同了

int main()

{

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

my_memcpy((arr1+2), arr1, 20); //字节的长度

int i = 0;

for (i = 0; i < 10; i++)

{

printf("%d ", arr1[i]);

}

return 0;

}

我们想要得到的是 1,2,1,2,3,4,5,8,9,10,但实际结果是:

实际上,这是因为memcpy是不能有内存重叠的,这样我们先更改了,然后再访问,因此出现了很多个1,2

当然,VS有保护机制,我们现在也可以使用memcpy来实现了,但理论上 是不行的

2.memmove

memmove和memcopy的差别是memmove函数处理源内存块和目标内存块是可以重叠的,最后返回目标空间的起始地址

函数原型

void* memmeove(void* dest, const void* src, size_t num)

现在,我们可以运用这个函数来实现了

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;

}

现在,我们来看看结果是否和我们想要的一样?

那么,我们是否可以尝试进行模拟这个函数呢?

第一种方法,我们在函数中再创建一个数组,将内容拷贝过去,然后再进行

那我们是否可以不创建新数组,来实现这个函数呢?

事实上,我们可以根据dest和scr的位置来判断

当dest在src之前时,我们从前向后进行拷贝,当dest在src后面时,我们从后向前进行拷贝,因此,我们可以写出以下的代码

void* my_memmeove(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;

}

3.memset

是用来完成内存设置的

函数原型:

void * memset(void* ptr,int vulue,size_t num);

ptr代表要填充的内存块的位置,vulue是设置的值,num是填充几个字节的位置

现在我们来使用这个函数吧!

int main()

{

char arr[] = "hello world";

memset(arr, 'x', 5);

printf("%s ", arr);

return 0;

}

这里,我们将前五个字符变成了x,结果如下:

当然,也不仅限于字符串函数,整形函数也可以,但是我们需要注意,这里是把所有的字节转换,而int类型占据4个字节,应该注意如何来运用

4.memcmp

完成内存块的比较

函数原型

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

从ptr1与ptr2开始num个字节进行比较,返回值是数字,前者大返回大于0的,后者大返回小于0的,相等返回0

我们来使用这个函数吧

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 ", ret);

return 0;

}

结果是这样

感谢您的观看

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。