目录
一.memcpy函数
cpp
void* memcpy(void* destination, const void* source, size_t num);
函数介绍
strcpy是复制字符串,而memcpy就是复制内存块。
memcpy会从source所指向的空间复制num个字节(不是元素个数而是字节)到destination所指向的空间。
source和destination所指向的的对象的类型是不重要的,这个函数仅仅是对二进制数据的拷贝。
这个函数与strcpy不同,它是不会管'\0'的,总是精准的复制num个字节。
为了避免越界。source和destination所指向的空间的大小至少应该是num个字节。
如果source和destination所指向的空间有所重叠,就不应该使用memcpy而是memmove;
- destination就是目标位置的指针。
- source就是指向源位置的指针。
- 就是需要复制的字节个数。(size_t是一种无符号整形)
为了针对任意类型的数据进行复制,所以参数的类型是void*类型的
memcpy函数的模拟实现
cpp
void* my_memcpy(void* destination, const void* source, size_t num)
{
void * ret = destination;
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
return ret;
}
int main()
{
char str1[20] = "xxxxx world";
char* str2 = "hello";
printf("%s\n", str1);
my_memcpy(str1, str2, 5);
printf("%s", str1);
return 0;
}
void*类型的指针是不能进行解引用的操作的,所以我们需要对其进行类型转换。之所以转化为char*类型的指针,那是因为1个字节可以确保任意字节数的内存块都可以复制,如果需要9个字节,使用int*类型就不行,因为int*的指针解引用得到的是4个字节,无法凑齐9.
注意:void*不是void,void*是有返回值的。
二.memmove函数
函数介绍
这个函数与memmmove函数几乎没有区别,但是memmove可以用于空间重叠的情况。
假设这这里的dest和source有一部分重叠了 。复制六个整形的话,5和六就重叠在了一起,那么这种情况下如何复制呢?
我们将source的数据依次向前复制,当5要被覆盖的时候,我们已经要用9了,这对复制并不会造成影响。
可换一种情况:
这时候我们就不能先将1复制给dest,因为我们再拷贝5的时候,5已经被覆盖了,我们想要的效果就没有达到。我们我们可以倒着复制先将6复制到10的位置上。
memmove函数的模拟实现
cpp
void* my_memmove(void* destination, const void* source, size_t num)
{
void* ret = destination;
if (destination < source)
{
while (num--)
{
*(char*)destination = *(char*)source;
((char*)destination)++;
((char*)source)++;
}
}
else {
while (num--)
{
*((char*)destination+num) = *((char*)source+num);
}
}
return ret;
}
int main()
{
char str1[20] = "xxxxx world";
char* str2 = "hello";
printf("%s\n", str1);
my_memmove(str1, str2, 5);
printf("%s", str1);
return 0;
}
三.memset函数
函数介绍
这个函数是用于设置内存的,设置ptr所指向的内存块的前num个字节为value值。
例子:
cpp
int main()
{
int arr[5] = { 1,2,3,4,5 };
memset(arr, 0, 20);//以字节为单位设置的
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
这个函数的模拟实现读者有兴趣,可以参考前面讲解的函数自行完成。
四.memcmp函数
函数介绍
比较ptr1和ptr2所指向的一个空间的前num个字节的内存,如果完全相等则返回0,反之则返回一个非0的数字。
这个函数与strcmp函数不同,它停止比较只取决于num,与'\0'字符无关。
返回值
这个返回值表明了这两个内存的关系
如果ptr1的值小于ptr2,就返回一个复制,反之返回值一个正数。这个值是前num个字符的ASCII值 之和计算的。
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;
}