大连做网站价格wordpress数据库名怎么修改
memcpy功能是内存拷贝
从source的位置拷贝前num个字节到destination内存中去,类型是void* (能接受任意类型的指针)。
注意:
1.num的单位是字节,函数结束会返回目的地的起始位置。
2.遇到'\0'不会停止。
3.只能处理不重叠的内存拷贝。
4.头文件是#include<string.h>。
函数实现:
#include<stdio.h>
#include<string.h>int main()
{int arr1[20] = { 0 };int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr1, arr2, 20);int i = 0;for (i = 0; i < 20; i++){printf("%d ", arr1[i]);}return 0;
}
运行结果:
我们来模拟实现一下该函数的功能:
#include<stdio.h>
#include<assert.h>void* my_memcpy(const void* dest, const void* src, size_t num)
{char* ret = dest;//要把目的地的起始地址先存起来assert(dest && src);//断言:需要解引用操作,不能是空指针while (num){*(char*)dest = *(char*)src;//因为传过来的类型不确定,void*需要强制转换成最小的类型char*,再解引用dest = (char*)dest + 1;src = (char*)src + 1;//强转是临时的,所以要再次转换num--;}return ret;//返回目的地的起始地址
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 40);int i = 0;for (i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;
}
看一下运行结果吧
最后说一下不重叠的内存拷贝:
还是那个代码,例如我们要从arr1的起始位置拷贝20个字节到arr1的下表为2的目的地去,那么我们预期的是什么样呢,应该是1,2,1,2,3,4,5,8,9,10。我们运行看结果:
我们可以看到结果并不是预期的那样,这是因为3,4的位置还没拷贝就被1,2覆盖了,所以5,6,7的拷贝都成了1,2,1。
当然这是我们模拟的memcpy函数,如果用库函数里的memcpy,结果是和我们预期的一样。
为什么会这样呢,是我们写的不对?并不是,memcpy函数只要实现了不重叠拷贝就行,只不过在vs上实现了重叠内存的拷贝,在其他的编译器上是不确定的。
以后我们需要重叠内存的拷贝最好不要用memcpy函数,专业的事还是交给专业的函数来做,memmove函数就是拷贝重叠内存的函数,memcpy能完成的事它都能做。
下次我们再分享其他内存函数,今天就到这里啦。