C语言memcpy等内存操作函数使用介绍

memcpy

内存拷贝

void * memcpy ( void * destination,const void * source,size t num ) ;

功能:函数从source中复制num个字节到destination中,并返回destination指针。 如果destination 和source 重叠,则函数行为不确定

因为参数的类型都是void*,所以传任何类型的数据都可以,传多少由第三个参数字节数来决定

void* my_memcpy(void* dest,const void* src, size_t num)
{
	assert(src && dest);	//断言
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;	/*因为num是字节个数,并且也不知传进来的是什么数据类型,所以把指针强转为char*类型,一										个字节一个字节传*/
		dest = (char*)dest + 1;		//void*	类型的指针不能++
		src = (char*)src + 1;
	}
	return ret;
}

memcpy函数应该拷贝不重叠的内存,拷贝重叠内存的情况应该交给memmove函数,而memcpy函数只要实现了不重叠拷贝就可以了,而VS中的实现既可以拷贝不重叠,也可以拷贝重叠内存,也就是说VS中的memcpy函数是按照memmove函数来实现的,但不保证其他编译器是这种情况,即

int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    my_memcpy(arr+2,arr1,20);		/*有内存重叠的情况,本意是想将1,2,3,4,5拷贝到3,4,5,6,7的空间内的,实际拷贝情况为										1,2,1,2,1,2,1,8,9,10*/
    return 0;
}

程序运行的大致过程如下图:

C语言memcpy等内存操作函数使用介绍_第1张图片

在第2次while循环后,src指向了下标为2的位置,这里存放了前面复制过来的1,dest指向了下标为4的位置,这里的元素是5,所以在进行第3次while循环时,将1复制到了5的位置,便又出现了元素1,后面步骤同理,所以用memcpy对内存重叠的操作不太友好

memmove

void *memmove( void *to, const void *from, size_t count );

功能: 与mencpy相同,不同的是当to 和 from 重叠,函数正常仍能工作。
即memmove函数可以处理内存重叠的情况

C语言memcpy等内存操作函数使用介绍_第2张图片

拷贝方法:

上图“前后”表示的是两个内存重叠的空间,数据是从旧空间的前面地址处开始拷贝到新空间的前面地址,还是从后面地址处开始拷贝到新空间的后面地址

右移:如将3 4 5 6 7移到8 9 10的内存空间中,允许有重叠的地方,所以此时要从后向前拷贝,即将7拷贝到10的位置,再将6拷贝到9的位置,依次类推,直到将3也拷贝过去,但3放在了原本6的位置,这样才能正确得将内存空间的所有数据完整拷贝到新空间,不会造成缺失

左移:如将3 4 5 6 7移到1 2的内存空间中,就要从前往后拷贝,即将3拷贝到1的位置,再将4拷贝到2的位置,依次类推

C语言memcpy等内存操作函数使用介绍_第3张图片

void* my_memmove(void* dest, void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	while (num--)
	{
		if (dest < src)		//从后面地址往前面地址拷贝,则字节从前往后拷贝
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
		else//从前面地址往后面地址拷贝,则字节从后往前拷贝
		{
			//每次字节数减一,便从尾字节向前进行拷贝
			//找到dest和src内存的尾字节的位置,然后拷贝
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

memset

void *memset( void *buffer, int ch, size_t count );

功能: 函数拷贝ch 到buffer 从头开始的count 个字符里, 并返回buffer指针。 memset() 可以应用在将一段内存初始化为某个值。例如:
memset( the_array, ‘\0’, sizeof(the_array) ); 这是将一个数组的所以分量设置成零的很便捷的方法。

注意:该函数是以字节为单位设置内存的

int arr[10]= { 0 };				//40个字节
memset(arr,1,20);				//往arr数组中前20个字节的内存放入1

结果:01 01 01 01 //要注意每个字节都设为1,4个字节的整型结果不是1

memcmp

内存比较
int memcmp( const void *buffer1, const void *buffer2, size_t count );

功能:函数比较buffer1 和 buffer2的前count 个字符(字节)。返回值如下:
Value 解释
less than 0 buffer1 is less than buffer2
equal to 0 buffer1 is equal to buffer2
greater than 0 buffer1 is greater than buffer2

equal to 0 buffer1 is equal to buffer2
greater than 0 buffer1 is greater than buffer2

跟之前的strcmp返回值一样

你可能感兴趣的:(C语言,c语言)