这个函数的作用是以字节为单位进行复制的。它与字符串函数中的strncmp函数有些类似,memcpy的应用范围更加广泛,而strncmp函数只适用于字符串,但memcpy函数适用于各种类型,因为它返回值为 void* ,形参列表中也是void* ,所以可以看出这个memcpy函数的适用范围比较广泛。具体用法如下:
注意:
1、函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2、这个函数在遇到 '\0' 的时候并不会停下来。
3、如果source和destination有任何的重叠,复制的结果都是未定义的。
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr, 20);
return 0;
}
分析:因为memcpy函数是按字节拷贝的,所以我在这是设置了20个字节,也就是5个整形,计算机的内存又是小端存储并且还是十六进制的,所以就是下面的样子。
void* my_memcpy(void* dst, const void* src, size_t num)
{
assert(dst && src);
void* ret = dst;
while (num--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;//将dst指针强转为char*类型此时指针解引用访问其地址上的一个
src = (char*)src + 1;
}
return ret;
}
上面将地址强制类型转换为char*字符指针类型,我相信很多人疑惑,在这里之所以要强制类型转换,是因为通过一个循环从起始地址往后直到第num个元素地址,解引用对应的每一个内存单元进行赋值操作,最后实现的指定内存空间num个内存单元的拷贝。用最小的char类型拷贝,可以适应所有的类型。
这个函数的作用是可以解决含有重复部分的数组之间的内存复制。该函数的形参类型,返回类型和memcpy函数是一样的,但是该函数增加了一个功能,就是可以处理源内存块和目标内存块重叠部分。
1、和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
2、如果源空间和目标空间出现重叠,就得使用memmove函数处理。
int main()
{
char arr[] = "abcdef";
memmove(arr + 1, arr, 4);
printf("%s\n", arr);
char arr1[] = "abcdef";
memmove(arr1, arr1 + 2, 4);
printf("%s\n", arr1);
return 0;
}
运行如下:
void* my_memmove(void* dst, const void* src, size_t num)
{
assert(dst && src);
void* ret = dst;
if (dst < src)
{
while (num--)
{
//从前往后拷贝
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)
{
//从后往前拷贝
*((char*)dst + num) = *((char*)src + num);
}
}
return ret;
}
这个函数的作用就是讲一个数组中前num个字节,设置组成value值,具体用法如下:
注意:
使用该函数注意设置的字节个数即内存单元的个数,不要超过了要设置的内存最大大小导致越界访问。
int main()
{
char arr[] = "abcdef";
memset(arr, '1', 3);
printf("%s\n", arr);
return 0;
}
运行如下:
void my_memset(void* arr, int value, size_t num)
{
assert(arr);
int i = 0;
for (i = 0; i < num; i++)
{
*((char*)arr + i) = value;
}
}
memcmp函数和strcmp函数用法极其相似,都是一个字节一个字节相比较的,比较的是ASCII的值,不过这函数可以比较任何类型的数据。
int main()
{
char arr[] = "123456";
char arr1[] = "abcdef";
int ret = memcmp(arr, arr1, 2);
printf("%d\n", ret);
return 0;
}
运行如下:
void* my_memcpy(void* dst, const void* src, size_t num)
{
assert(dst && src);
void* ret = dst;
while (num--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return ret;
}
本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。