strcpy拷贝的仅仅是字符串,但是内存中的数据不仅仅是字符,所以就有了memcpy函数
void *memcpy (void * destination ,const void * source , size_t num)
函数memcpy从source的位置开始向后拷贝num个字节的数据到destination的内存位置
- #include
- int main()
- {
- int arr1[10] = { 0 };
- int arr2[] = { 1,2,3,4,5 };
- //把arr2中的前5个整形的数据,拷贝放到arr1中
- memcpy(arr1, arr2, 20);
- return 0;
- }
可以看到前5个整形都拷贝过来了

(1)一个字节一个字节的拷贝(dest,src转为char *)
eg:如果拷贝7个字节(两个int *类型指针不能操作)
(2)(char *)dest++不能这样写,因为++的优先级高于强制类型转换
相当于先对原类型进行++,再进行进行强转
前置++(char *)dest虽然C语言中可以,但是改为c++就不能运行,所以还是正常写+1
- #include
- #include
- void* my_memcpy(void* dest, const void* src, size_t sz)
- {
- void * ret=dest;
-
- assert(dest && src);
-
- while (sz--)
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest + 1;
- src = (char*)src + 1;
- }
- return ret;
- }
一个数组arr={1,2,3,4,5,6,7,8,9,10},如果想在自身的基础上进行拷贝,即把1,2,3,4,5拷贝到3,4,5,6,7的位置上,想得到结果:1,2,1,2,3,4,5,8,9,10
但是得到的结果却是1 2 1 2 1 2 1 8 9 10
我们就发现不重叠内存的拷贝,可以使用memcpy,
重叠内存的拷贝,使用memmove函数
上面其实是标准规定,但是实际在VS2022这个环境中,memcpy也能实现重叠内存的拷贝
(其他平台不一定)
- #include
- #include
- #include
- void* my_memcpy(void* dest, const void* src, size_t sz)
- {
- assert(dest && src);
-
- while (sz--)
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest + 1;//这里不能写成(char*)dest++,强制类型转化是临时的,++的时候dest并不一定是char*类型的
- src = (char*)src + 1;
- }
- }
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
- my_memcpy(arr + 2, arr, 20);
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
void *memmove(void * destination ,const void * source , size_t num)
参数和memcpy一样,但是memmove可以实现重叠内存的拷贝
(这里不考虑直接开辟一个相同的空间再进行拷贝元素)
讨论:
dest
dest>src:只能从后向前拷贝
dest和src不相干的时候:从后往前或者从前往后都可以

- #include
- #include
- void* my_memmove(void* dest, const void* src, size_t sz)
- {
- void* ret = dest;
- assert(dest && src);
-
- if (dest < src)
- {
- //前->后
- while (sz--)
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest+1;
- src = (char*)src+1;
- }
- }
- else
- {
- //后->前
- while (sz--)
- {
- *((char*)dest + sz) = *((char*)src + sz);
- }
- }
- return ret;
- }
- int main()
- {
- int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
- my_memmove(arr , arr+2, 20);
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
int memcmp ( const void * ptr1,const void *( ptr2 , size_t num )
类似strcmp函数,memcmp是一对字节一对字节进行比较,比较num个字节ACSII值
(1)返回值:
- #include
- #include
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7 };
- //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
-
- int arr2[] = { 1,2,3,0x11223304 };
- //01 00 00 00 02 00 00 00 03 00 00 00 04 33 22 11
- int ret = memcmp(arr1, arr2, 13);
-
- printf("%d\n", ret);
- }
上面这个代码虽然arr1的元素多,但是比较前13个字节的大小都一样,那么ret=0
void *memset( void *dest, int c, size_t count )
复制字符c(一个无符号字符)到参数str所指向的字符串的前n个字符
(初始化前count个字节为c)
是以字节为单位设置内存的
eg1:将hello world中的wor改为xxx:
- #include
- #include
- int main()
- {
- char arr[] = "hell0 world";
- memset(arr + 6, 'x', 3);
- printf("%s\n", arr);
-
- return 0;
- }
eg2: 思考这个代码将arr改为了啥?
- #include
- #include
- int main()
- {
- int arr[10] = { 0 };
- memset(arr, 1, 40);
- return 0;
- }

每一个int类型的元素的每一个字节都改为了1
所以想把数组每一个元素都初始化为1,用memset函数是不可能实现的
但是可以都初始化为0
本次内容就到此啦,欢迎评论区或者私信交流,觉得笔者写的还可以,或者自己有些许收获的,麻烦铁汁们动动小手,给俺来个一键三连,万分感谢 !
