#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int arr1[20] = { 1,2,3,4,5,6,7,8,9 };
int arr2[20] = { 0 };
strcpy(arr2, arr1);
return 0;
}
strcpy函数:C语言函数:字符串函数及模拟实现strlen() 、strcpy()、 strcat()_srhqwe的博客-CSDN博客
以上代码,如果用strcpy()函数,想将arr1拷贝到arr2中,要明白strcpy()是字符串拷贝函数,这样使用strcpy()会出现问题:
类型不一样arr1和arr2是int类型,strcpy只接收char*类型。如果强行将arr1内容拷贝到arr2中,当是小端存储时,strcpy()访问完一个字节01后,当要访问第二个字节00时,发现00是ASCII码值为0,strcpy会认为这是\0,然后停止向后继续拷贝。最后arr2只拷贝了01过去,arr2的则变成了0.
因为strcpy不能将arr1拷贝到arr2,因此就急需一个函数是针对内存块进行拷贝的。只要你是针对内存块拷贝,无论你是何种类型,何种数据,都可以进行拷贝:
头文件:#include
函数类型是void*指针,说明返回的是任何类型指针的destination。
destination和source与strcpy()一样,只是类型变成了void*
size_t num是最关键的,意思是:从destination中拷贝num个字节到source中,
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1,20);
return 0;
}
此时要将arr1中的1,2,3,4,5拷贝到arr2中,一个int是4字节,5个int就是20字节,因此num传入20,结果:
其中20可以使用sizeof(int),算出一个int大小,再x上5,也可以得到20
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1,5*sizeof(int));
return 0;
}
创建:void* my_memcpy(void* dest, const void* sour, size_t num)
size_t == (unsigned)int----------只有正数
#define _CRT_SECURE_NO_WARNINGS
#include
void* my_memcpy(void* dest, const void* sour, size_t num)
{
for (int i = 0; i < num; i++)
{
*((char*)dest + i) = *((char*)sour+i);
}
return dest;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1,5*sizeof(int));
return 0;
}
因为dest是void*,不能通过+1或++之类的操作符对他进行改变。因为计算机并不知道void*+1跳多少字节。如果+1首先代码行就会变成红色(出错)
这里将dest和sour强制类型转换成char*,那么每次+i就能移动一个字节。可以保证每个字节都做出了改变。
如果强制类型转换成int或其他的类型,这个函数就有了局限性。+1就跳4字节。那么中间这四个字节没有做出改变,如果此时传入char类型的数据,那么就会使得内容缺失。
#define _CRT_SECURE_NO_WARNINGS
#include
void* my_memcpy(void* dest, const void* sour, size_t num)
{
for (int i = 0; i < num; i++)
{
*((char*)dest + i) = *((char*)sour+i);
}
return dest;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr1+2, arr1,5*sizeof(int));
return 0;
}
如以上代码,memcpy函数从arr1拷贝的内容放到了&arr1[2]上。
如果正常此时按照这样拷贝,arr1中就会变成1,2,1,2,3,4,5,8,9,10
但是实际上却是:
显然与预期不符,那么为啥呢?
当从arr1上拿数据放到arr1+2中[3][4]的两个位置变成了1,2;
arr1[3]和arr[4]以及变成了1,2;此时又从这两个地方拿数据放到[5][6],这两个位置也变成了1,2.以此类推。最后得到了1,2,1,2,1,2,1,8,9,10
那么如何才能达到预期的效果呢?
C语言函数:内存函数memmove()以及实现与使用。_srhqwe的博客-CSDN博客
这里我们使用的my_memcpy函数,出现了内存重叠问题。
我们再试试VS库里的memcpy函数:
发现:VS库内的memcpy函数竟然不会遇到内存重叠问题,那是我们写错了吗?
其实,memcpy函数标准是:只需要实现不重叠拷贝。而VS库内的memcpy函数也实现了重叠拷贝。也就是说,VS库内的memcpy函数比标准更nb。
而VS库内的memcpy函数,也是按照memmove函数来实现的。