文章目录
- 1.memcpy使用和模拟实现
- 2.memmove使用和模拟实现
- 3.memset函数的使用
- 4.memcmp函数的使用
memcpy:内存拷贝
memmove:内存移动
memset:内存设置
memcmp:内存比较
1.memcpy使用和模拟实现
memcpy:内存拷贝
void * memcpy ( void * destination, const void * source, size_t num );
                    目标空间的地址          源空间的地址        被拷贝的字节个数
返回的是目标空间的起始地址
void*指针接收任意参数的地址
函数
memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。这个函数在遇到 ‘
\0’ 的时候并不会停下来。如果
source和destination有任何的重叠,复制的结果都是未定义的。
#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num) {
	int i = 0;
	void* ret = dest;
	assert(src && dest);
	while (num--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	//将arr1中的34567拷贝到arr2中
	my_memcpy(arr2, arr1 + 2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}
打印:
3 4 5 6 7 0 0 0 0 0
注意:对于重叠的内存,交给
memmove来处理。重叠的意思就是:
my_memcpy(arr1 + 2, arr1, 20);比如你想把
arr数组里的某些数用arr数组的某些数替换,这样会出问题。
例如:
void* my_memcpy(void* dest, const void* src, size_t num) {
	int i = 0;
	void* ret = dest;
	assert(src && dest);
	while (num--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//我们的想法是:将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖
	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 1 2 1 8 9 10
打印这个玩意儿?怎么和猜的不一样呢?
1 2 3 4 5 6 7 8 9 10程序里先把1替换了3
1 2 1 4 5 6 7 8 9 10然后2替换了4
1 2 1 2 5 6 7 8 9 10然后原来3位置的1替换了5
1 2 1 2 1 6 7 8 9 10然后原来4位置的2替换了6
1 2 1 2 1 2 7 8 9 10然后原来5位置的1替换了7
1 2 1 2 1 2 1 8 9 10
memcpy函数不负责重叠内存的拷贝,只负责不重叠的内存,非要使用,结果就是未定义的。
不过说是这么说,有些时候memcpy也能实现重叠内存的拷贝。我们可以认为memcpy实现的拷贝不一定都对。所以重叠就用memmove函数。
memmove函数来处理重叠内存的拷贝。
2.memmove使用和模拟实现
memmove:内存移动
void * memmove ( void * destination, const void * source, size_t num );
和
memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。
#include <string.h>
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖
	memmove(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

这个函数实际上就是实现src拷贝到dest。
如果是上面一种情况的话,我们可以先把3给1,然后把4给2,然后把5给3…这样就可以实现重叠内存的处理。(从前向后)
如果是中间一种情况的话,我们可以先把7给9,然后把6给8,然后把5给7…这样就可以实现重叠内存的处理。(从后向前)
如果是下面一种情况的话,我们可以按顺序把3给8,把4给9,把5给10…这样就可以实现重叠内存的处理。(从后向前)

两个紫色竖线表示的位置分别为
src的起始位置和结束位置。这两根紫色竖线把情况分成了三种。
第一种情况是(从前向后)
第二种情况是(从后向前)
模拟实现:
void* my_memmove(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(src && 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;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//将arr1中的12345拷贝到arr1中原来34567的地方,将原来的覆盖
	my_memmove(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
3.memset函数的使用
memset:内存设置
void * memset ( void * ptr, int value, size_t num );
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
#include <stdio.h>
#include <string.h>
int main ()
{
    char str[] = "hello world";
    memset (str,'x',6);
    printf(str);
    return 0;
}
打印:
xxxxxxworld
4.memcmp函数的使用
memcmp:内存比较
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
返回值如下:

#include <stdio.h>
#include <string.h>
int main()
{
    int arr1[] = { 1,2,3,4,5 };
    //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
    int arr2[] = { 1,2,3,6,5 };
    //01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00
    int ret = memcmp(arr1, arr2, 12);
    printf("%d\n", ret);
    return 0;
}
打印:
0
因为前12个字节一样
#include <stdio.h>
#include <string.h>
int main()
{
    int arr1[] = { 1,2,3,4,5 };
    //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
    int arr2[] = { 1,2,3,6,5 };
    //01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00
    int ret = memcmp(arr1, arr2, 13);
    printf("%d\n", ret);
    return 0;
}
打印:
-1
因为第13个字节不一样



















