一、memcpy函数
使用前需要 #include<string.h>
该函数最后会返回destination的地址;
函数memcpy从source的位置开始向后复制num个字节
并且该函数遇到\0不会停止复制
source和destinetion部分不能出现重叠部分,否则可能出问题
-----------------------------------------------------------------------------------
对于该函数你可以对任意类型的数组进行拷贝和粘贴操作,因为形参部分是void*,可以接收任何类型的指针
经过简单的讲解,我们下面来模拟实现一下memcpy函数
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
void* ret = destination;
assert(destination && source);
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
return ret;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
my_memcpy(arr + 2, arr, sizeof(int) * 2);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
}
通过一个字节一个字节地拷贝粘贴来进行操作
运行后结果为
符合要求
-------------------------------------------------------------------------------------------------------------------------------
注意 若想要达成像如图所示的效果,能否通过my_memcpy(arr+3,arr,sizeof(int)*4)进行操作,
答案是否定的
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
void* ret = destination;
assert(destination && source);
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
return ret;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
my_memcpy(arr + 3, arr, sizeof(int) * 4);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
}
我们原本期待打印出 打印出来的结果是 1 2 3 1 2 3 4 8 9 0
但是实际结果是
这是因为该数组原来的4先被1拷贝粘贴后给覆盖了,所以后面作为source的第四个就变成了1,所以后面拷贝粘贴的也是1
memcpy函数也存在这样的问题,所以说如果source部分和destination部分如果有重叠可能不会是我们想要的结果,memcpy是用来处理不重叠的内存拷贝
而这个时候memmove函数可以帮我们实现这个效果
但是在我自己使用的vs编译器上发现用memcpy这个函数也可以实现具有重叠部分的拷贝粘贴
这是为什么呢?
因为我们对memcpy函数的要求只是能够进行不重叠的拷贝粘贴就行了,但是vs编译器还实现了对重叠部分的拷贝粘贴
但是并不是说所有的编译器都是这样
所以说重叠的内存拷贝粘贴还是交给memmove函数
memmove函数不仅能实现重叠部分函数的拷贝粘贴,还能够实现没有重叠部分函数的拷贝粘贴
二、memmove函数
头文件和上面的一样
memmove对source和destination有重叠部分的函数进行拷贝粘贴实现
#include<stdio.h>
#include<string.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
memmove(arr + 3, arr, sizeof(int) * 4);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
}
满足了我们刚才在讨论memcpy函数时的需求
------------------------------------------------------------------------------------------------------------------------
我们再模拟实现一下memmove函数
#include<stdio.h>
#include<string.h>
#include<assert.h
void* my_memmove(void* destination, const void* source, size_t num)
{
void* ret = destination;
assert(destination && source);
if (destination < source) /*这种情况从前往后复制粘贴,可以避免source里有些元素没有复制粘贴就被覆盖*/
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
else
{
while (num--) /*从后往前复制粘贴,可以避免source里有些元素没有复制粘贴就被覆盖*/
*((char*)destination + num) = *((char*)source + num);
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
memmove(arr + 3, arr, sizeof(int) * 4);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
}
三、memcmp函数
memcmp函数是一个字节一个字节进行比较当
最后的num表示最多要比较的字节,也就是说如果在之前就比较出来了是可行的
mencmp函数比较时,第一个比第二个大,返回正数,第一个比第二个小,则返回负数,若相等,则返回0
#include<stdio.h>
#include<string.h>
int main()
{
int i = 0;
int arr1[10] = { 1,2,3,4,5,1,7,8,9,0 };
int arr2[10] = { 1,2,3,4,5,257 };
int a=memcmp(arr1, arr2,21 );
printf("%d", a);
return 0;
}
这两个数组前21个字节都是这个
一样所以运行后
---------------------------------------------------------------------------------------------------------------------------
#include<stdio.h>
#include<string.h>
int main()
{
int i = 0;
int arr1[10] = { 1,2,3,4,5,1,7,8,9,0 };
int arr2[10] = { 1,2,3,4,5,257 };
int a=memcmp(arr1, arr2,22 );
printf("%d", a);
return 0;
}
arr1前22个字节
arr2前22个字节
所以从第一个字节开始比,比到第22个字节arr2大于arr1的
所以运行结果
四、memset函数
memset函数就是将ptr指向及的向后的num个字节的内容改为value
比如
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "hello world";
memset(arr + 3, 'x', 5);
printf("%s", arr);
return 0;
}
结果是
但是注意memset函数千万不要像下面那样使用
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
memset(arr, 1, 5);
for (int i = 0; i < 7; i++)
printf("%d ", arr[i]);
return 0;
}
原本你想的是打印出来是1 1 1 1 1 6 7
可是实际结果是
分析一下
这里分别代表执行函数前后
发现这里是将arr前5个字节改为了1
所以说要记住memset是以字节为单位进行修改
小结
这是我对一些内存函数的简单介绍,如有问题欢迎大家的纠错批评