C/C++中的mem函数和strcopy函数的区别和应用

2020-01-06 15:42:16于丽

memmove

它与memcpy的功能相似,都是将src所指的n个字节复制到dst所指的内存地址的起始位置,不同的是它处理了src和dst有重叠的情况。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。(与上述修改过得memcpy基本一致)

所以基本原则就是,如果你能确保两段内存没有重叠的部分,就使用memcpy来进行拷贝;如果你不能确定,为了保证复制的正确性,必须用memmove。

其实现代码如下:


void*memmove(void* dest,void* src,size_tcount)
{
void* ret = dest;
if(dest <= src || dest >= (src + count))
{
//Non-Overlapping Buffers
//copy from lower addresses to higher addresses
while(count --)
*dest++ = *src++;
}
else
{
//Overlapping Buffers
//copy from higher addresses to lower addresses
dest += count - 1;
src += count - 1;
while(count--)
*dest-- = *src--;
}
returnret;
}

strcpy

strcpy是C语言的标准库函数,使用strcpy需要包含以下头文件:


#include<string.h>
#include<stdio.h>

其函数功能是把从src地址开始且含有NULL结束符的字符串复制到dst开始的地址空间,返回指向dst的指针。其函数代码如下:


char*strcpy(char* dst ,char* src){
if(dst==NULL||src==NULL)returnNULL;// --1
if(dst==src)returndst;//--2
char* address = dst;//--3
while((*dst++ = *src++)!='')//--4
returnaddress;//--5
}

图中标出来的都是考点,下面一一说明:

1、需要判断参数的正确性,这里也可以抛出一个异常

2、如果指向了同一块内存,不用复制直接返回即可

3、这里需要保存原始的dst指针,用作返回值

4、这里有一个技巧,如果写成以下两种,面试的时候会大大扣分!


//第一种
while(*dst++ = *src++)//直接越界访问,没有检查指针的有效性
//第二种
while(*src!=''){*dst++ = *src++;}//考虑了src的边界问题,没有在dst的后面加'',会导致dst的长度未知引起错误

5、函数返回dst的原始值是为了能够支持链式表达式,增加了函数的附加性。

上述第5点可以用如下测试代码来说明:

intlength =strlen(strcpy(strA,strB));//如果不支持链式表达式,这里会报错。

那么有时候也会问为什么不返回src的原始值,错误原因有以下三点:

源字符串本来就已知,返回没有什么意义

不能支持形如char * strA = strcpy(new char[10],strB) 这样的表达式
为了保护源字符串,使用const限定了src所指的内容,把const char作为char 的返回值,类型不符,编译器会报错。

strcpy和memcpy主要有以下3方面的区别。

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。