Memcpy,Memmove,Memcmp函数详解

Memcmp

为什么有了strcpy还要有memcpy
因为strcpy是用来拷贝字符和字符串的,strcpy是按字节拷贝的,一个字节一个字节去拷贝,strcpy是不能用来拷贝其他类型的,所以应运而生了memcpy
memcpy函数原型
void *memcpy( void *dest, const void *src, size_t count );
count为要拷贝的字节数,单位是字节
使用memcpy
#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[10] = { 0 };
	int arr2[3] = { 1,2,3 };
	memcpy(arr1, arr2, 12);
	return 0;
}
模拟实现memcpy
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
	size_t i = 0;
	assert(destination != NULL);
	assert(source != NULL );
	char* dest = (char*)destination;
	char* sour = (char*)source;
	for(i=0;i<num;i++)
    {
       dest[i] = sour[i];
     }
	return destination;
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3 };
	my_memcpy(arr1, arr2, 12);
	return 0;
}
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{
	//每次拷贝一个字节最为合适
	assert(dest != NULL);
	assert(source != NULL);
	size_t i = 0;
	char* ret = (char*)dest;
	char* s1 = (char*)dest;
	const char* s2 = (char*)source;
	for (i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)source;
		s1++;
		s2++;
	}
	return ret;
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3 };
	my_memcpy(arr1, arr2, 12);
	return 0;
}
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{
	//每次拷贝一个字节最为合适
	void* ret = dest;
	assert(dest != NULL);
	assert(source != NULL);
	while (num--)
	{
		*(char*)dest = *(char*)source;
		((char*)dest)++;
		((char*)source)++;
	}
	return ret;
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3 };
	my_memcpy(arr1, arr2, 12);
	return 0;
}
memcpy函数的注意事项
  • 函数memcpy从source位置开始向后复制num个字节的数据到dest内存位置
  • 这个函数在遇到\0的时候并不会停下来
  • 如果source和dest有任何的重叠,其结果是未定义的,也就是说memcpy不处理这种情况。

Memmove

memmove的函数原型
void *memmove( void *dest, const void *src, size_t count );
memmove的拷贝会分为以下的两种情况
如下图所示:

分情况讨论

  • 一种是dest>source
  • 另一种是source<dest
    在这里插入图片描述
memmove的函数原型
void *memmove( void *dest, const void *src, size_t count );
模拟实现memmove
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, int count)
{
	int i = 0;
	assert(destination != NULL);
	assert(source != NULL);
	if (destination < source)
	{
		//从前往后拷贝
		char* dest = (char*)destination;
		char* sour = (char*)source;
		for (i = 0; i <count; i++)
		{
			dest[i] = sour[i];
		}
	}
	else
	{
		while (count--)
		{
			*((char*)destination + count) = *((char*)source + count);
		}
	}
	return destination;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1 + 2, arr1, 16);
	return 0;
}
memmove函数的注意事项
  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以有重叠的
  • 如果源空间和目标空间出现重叠的部分,就要使用memmove函数进行处理

Memcmp

memcmp函数原型

int memcmp( const void *buf1, const void *buf2, size_t count );

memcmp—>在两个缓冲区比较(在缓冲区中比较两个字符)

#include<stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4 };
	int arr2[] = { 1,2,4,5 };
	int ret = memcmp(arr1, arr2, 12);
	printf("%d", ret);
	return 0;
}
返回值和strcmp的含义一样
  • 返回值 > 0 ptr1 > ptr2
  • 返回值 = 0 ptr1 == ptr2
  • 返回值 < 0 ptr1 < ptr2
模拟实现
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	assert(ptr1&&ptr2);
	const char* ch_ptr1 = (char*)ptr1;
	const char* ch_ptr2 = (char*)ptr2;
	while (num&&*ch_ptr1&&*ch_ptr2)
	{
		if (*((unsigned char*)ch_ptr1) > *((unsigned char*)ch_ptr2)) //注意库中的都是转成无符号整数
		{
			return 1;
		}
		else if (*((unsigned char*)ch_ptr1) < *((unsigned char*)ch_ptr2))
		{
			return -1;
		}
		else
		{
			ch_ptr1++;
			ch_ptr2++;
			num--;
		}
	}
	if (num == 0)
		return 0;
	if (*ch_ptr1 == '\0')
		return -1;
	if (*ch_ptr2 == '\0')
		return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int my_memcmp1(const void *p1, const void *p2, size_t count)//方法1
{
    assert(p1);
    assert(p2);
    char *dest = (char *)p1;
    char *src = (char*)p2;
    while (count && (*dest == *src))
    {
        count--;
        dest++;
        src++;
    }
    if (count == 0)
        return 0;
    return *dest - *src;
}
int my_memcmp2(const void *p1, const void *p2, size_t count)//方法2
{
    assert(p1);
    assert(p2);
    int ret = 0;
    char *dest = (char *)p1;
    char *src = (char*)p2;
    while (count && (!(ret = (*dest - *src))))
    {
        dest++;
        src++;
        count--;
    }
    if (ret > 0)
    {
        return 1;
    }
    else if (ret < 0)
    {
        return -1;
    }
    return 0;
 
}
int main()
{
    int arr1[] = {1,2,3,4,5,6};
    int arr2[] = {1,2,3,1000000,5,6};//清楚内存是怎样放置的
    int ret = my_memcmp2(arr1, arr2, 16);
    printf("%d", ret);
    system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章