memmove与memcpy用法区别

memmove与memcpy用法区别

memmove函数

#include <string.h>
void *memmove(void *dest, const void *src, size_t n);

功能:由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。
返回:memmove()函数返回指向dest的指针。
注意: 在使用的过程中,发现一个问题,如果源地址中的拷贝字节数 n < strlen(dest),即源地址拷贝字节小于目的地址数据,当源数据当中有\0时,则将目的地址替换的位置后面全部清空。

#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

功能: memcpy()函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存区域不能重叠。
返回:memcpy()函数返回指向dest的指针。

图片来源与网络:
在下图的情况下进行拷贝,两个函数无差别。
在这里插入图片描述
但如果如下图情况,出现重叠部分,memcpy()源地址拷贝到目的地址时,可能会把拷贝到目的地址的数据又放回到源地址,这样肯定不是我们想要的结果。而memmove()则不会出错。
在这里插入图片描述

举个例子:

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    float   buf3 = 23.33;
    int     i;  
    //char fb[20] = {0x32, 0x33, 0x2e, 0x33, 0x33};   //ASCii码当中的十六进制表示
    char    fb1[20] = "123456789";
    char    fb2[20] = "123456789";
    char    fb3[20] = "123456789";
    char    fb4[20] = "123456789";    

    //有重叠时才能体现memmove与memcpy的区别
    memmove(&fb1[3], fb1, 6); 
    printf("%s\n", fb1);
    memcpy(&fb2[3], fb2, 6); 
    printf("%s\n", fb2);
    
    //未重叠时memmove与memcpy功能无差别
    memmove(&fb3[0], &fb3[3], 5); 
    printf("%s\n", fb3);
    
    memcpy(fb4, &fb4[3], 5); 
    printf("%s\n", fb4);
   	
   	return 0;

运行结果如下:

123123456	//memmove
123123423	//memcpy
456786789
456786789

拷贝时,有地址重叠则memcpy拷贝出错。
无重叠它们功能无差别。

另外再题下关于strlen使用的注意:

自己遇到了坑,老是提示段错误,发现计算长度已经越界了。

	char * str1 = "abc";                             
	char * str2 = "ab\0c";
	char * str3 = "ab\\0c";
	char * str4 = "abc0c";
	char arr0[5] = {'1', '2', '3', '4', '5'};
	char arr1[5] = {'1', '2', '3', '4', '\0'};
	char arr2[5] = {'1', '2', '3', '4', 0};
	char arr3[5] = {'0', '0', '0'};
	char arr4[5] = {0, 'a', 'b'};
	char arr5[5] = {'a', '\0', 'b'};
	char arr6[5] = {'a', 0, 'b'};

进行strlen计算时的结果如下:

 3 2 5 5 未知 4 4 3 0 1 1

通过这个可以知道:

  1. strlen遇到\0就直接结束,因为十进制0的ASCII码是\0
  2. 字符串会默认在末尾加上\0,所以计算时不会出现错误,得到的是真实数据;
  3. 计算字符时,因为字符数组当中没有\0的话,不会结束,这时已经超出数组,计算的长度就无法确定了。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值