在模拟实现qsort的时候,我们知道的是这个函数的返回值是void,这个函数的第一个形参是void* base,因为这个函数可以排序的是任何类型的数据,所以,他就用void* ,因为创造这个函数的人不知道使用者到底要排序的是什么类型的数据,所以用void* 来代替。那么讲这些的作用是什么呢?下面我们在实现memcpy和memmove的时候用到了这个知识点。
1.memcpy
这个函数的第一个参数和第二个参数就不在详细讲,上篇博客都详细说过,来说说第三个参数,第三个参数是多少个字节,是以字节为单位的 ,而不是元素,这个一定要分清楚,不然在拷贝的时候会出现意想不到的错误。
那么下面就来看看这个函数的是怎么使用的吧:
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr1[20] = { 0 };memcpy(arr1, arr, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
这个函数的使用方法如上,没什么好说的,就是拷贝数据。
下面来看看我们模拟实现的:
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && &src);while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr1[10] = { 0 };my_memcpy(arr1, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
这里详细讲一下实现过程,这个函数的实现思路其实很简单的,就是一一赋值,这里因为我们不知道使用者想要拷贝什么类型的数据,所以就是我们要把强制类型转换为char*,这样就可以一个一个字节的拷贝了,但是要注意的是,强制类型转换是临时的,也就是不是永久性的,这个要谨记,不然拷贝的时候会报错。下面来看看我们打印结果:
因为要拷贝的是20个字节,也就是5个整形数据,所以这里是1234500000.
2.memmove
这个函数的功能是拷贝,和上面的函数功能一样,但是他们两有明显的区别,等会会详细讲。
先看看库里函数的代码以及打印:
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr1[10] = { 0 };memmove(arr1, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
这个就不再多说,直接看我们是怎么模拟实现的这个函数 :
void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*(char*)((char*)dest + num) = *(char*)((char*)src + num);}}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr1[10] = { 0 };my_memmove(arr1, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
代码以及打印结果都在上面,下面就说说这两个之间的区别吧,因为这两个都是拷贝数据,所以他们之间肯定会有所不同,先说memcpy,不知道有没有人在思考的是怎么给自己拷贝,也就是拷贝的时候重叠数据的问题,这个时候怎么办,还能用这个函数吗,答案是肯定的不能,这时候就用上 memmove这个函数了,为啥呢?因为这个函数虽然也是拷贝,但是你可以理解为他的作用范围比memcpy的范围广,能力比memcpy的强就可以了。所以在拷贝的时候,不知道该用哪个函数的时候,就用memmove(个人建议)
最后,如果你觉的本篇本科对你有用的话,就点一下赞吧!谢谢支持!