学习使用void*指针时,我们需要知道什么时候使用此类指针,以及它有什么样的作用。
当我们学习或者使用库函数时,你是否想过为什么一些函数能传字符型的参数,又能传整型参数呢?并且又是如何接收它们的,这个时候,就是使用void* 指针接收的
以模拟实现memcpy函数为例,简单点说,此函数的作用就是将一个字符串的内容拷贝到另一个字符串,那么直接上代码
#includevoid* my_memcpy(void* str1 , void* str2 , int num) { void* ch = str1; while(num--) { *(char*)str1 = *(char*)str2;//在这里,我通过强制类型转换,然后通过一个字节一个字节的进行交换 str1 = (char*)str1 + 1;//这里的强制类型转换则是为了加1时仅跳过一个字节 str2 = (char*)str2 + 1; } return ch;//为什么有返回值呢?可能这是你们的疑惑,首先此函数不是void型,自然就有返回值 } int main() { int arr2[10] = {1,2,3,4,5,6,7,8,9,10}; int arr1[10] = {0}; my_memcpy(arr1 , arr2 , 20);//第一个参数是我吗需要改变的数组,第二个是拷贝的内容,第三个参数是我们需要进行交换的字节个数 int i = 0; for(i = 0; i<=4; i++) { printf("%d" , arr1[i]); } return 0; }
因为我们使用void*来写函数时一般都是为了函数能够在char型或者int型等等都能使用,所以我们需要一个字节一个字节的交换
并且从上面可以明显看出void*指针能够接收任意类型的指针,这也就是设置这些函数最基本的知识。
不过显然此函数有明显的缺点,因为它无法通过自己来重新对自己重新赋值。因为它的地址是相同的。例如把数组中的 1,2,3,4,5对4,5,6,7,8进行赋值时会发现
4 -> 1 5 -> 2 6 ->3 (4 ->1 8 -> 2)因为地址相同所以后面的元素进行重新赋值时会发生错误
而一般对自己进行自己重新赋值时需要使用memmove来实现
接下来以模拟实现memmove来使你的知识更熟练吧
#includevoid* my_memmove(void* str1 , void* str2 , int num) { void* tmp1 = str1; void* tmp2 = str2; void* ch = str2; if(str1 > str2) { while(num--) { str1 = tmp1; str2 = tmp2; str2 = (char*)str2 + num; str1 = (char*)str1 + num; *(char*)str1 = *(char*)str2; } } else { while(num--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } } return ch; } int main() { int arr1[10] = {1,2,3,4,5,6,7,8,9,10}; my_memmove(arr1+2 , arr1 , 20); int i = 0; for(i = 0; i<=9; i++) { printf("%d " , arr1[i]); } return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)