memcpy
#include <string.h>
void *memcpy(void *dst,const void *src,unsigned int len)
{
if((NULL==dst)||(NULL==src))
return NULL;
char *Strdst = (char *)dst;
while(len--)*dst++=*src++;
return Strdst;
}
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
函数返回一个指向dest的指针。
由于memcpy拷贝的数据并不限于字符串,理论上可以是指向任何类型的数据指针,因此这里设计为void *类型。
strcpy
//C语言源码
char * strcpy(char* dst,const char *src)
{
if((src==NULL)||(dst==NULL))
return NULL;
char *strdst=dst;
while((*dst++=*src++)!="\0");
return strdst;
}
/*注意
在C++或者VS 2017上使用strcpy会报错,即使加上了 #include<cstring>
这个时候需要在#include 之前加上
#define _CRT_SECURE_NO_WARNINGS
我们通过疑问来解析strcpy
为什么要有函数返回值,并且返回值类型为char *?
为了更好地使用这个函数,字符串拷贝并不一定成功,比如传递的参数有问题,那么就通过返回特定的值进行查错就很有意义。其次,拷贝成功后返回目的地址也很合理,使用也更加方便,因为把字符串从一个地方(src指向的地方)拷贝到另外一个地方(dst指向的地方)后接下来一般都会访问dst指向的地方。
char table[100];
char *buf = strcpy(table,"shenzhen");
为什么函数的第二个形参要用const修饰?
用const修饰就可以阻止src指向的区域被修改,const修饰*src,即修饰src指向的区域,函数只能对该区域进行只读操作。
为什么要进行参数合法性检查?为什么不写成if((!dst)||(!src))?
①如果src的值为NULL,那么就会把一个非法区域的数据拷贝到dst指向的缓冲区中,而这很容易造成内存越界(因为很有可能很晚才遇到"\0"标记符或者无法遇到"\0"标记符);如果dst的值为NULL,那么就相当于把一串数据拷贝到一些非法区域,从而造成系统崩溃。
②因为dst和src类型为char*,并不是BOOL类型,虽然if((!dst)||(!src))可以进行从char*到BOOL的隐形类型转换,但是这相当于把可靠性交给了第三方去维护,显然不是一个合格程序员的素养。
为什么while循环里面要判断!="\0"?为什么while循环不写成while (*strSrc!='\0') *dst++=*src++?
答:①字符串都是以"\0"作为结束标志的,即便你写一个字符串"shenzhen",系统也会自动在结尾增加"\0",只是你看不到而已。
②这样写就会导致字符串的"/0"无法拷贝到目的区域,这是不行的。
区别
与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。如果第二个字符串参数没有n个字节怎么办?依然能拷贝成功。
strcpy只用于字符串拷贝,并且是任意长度的字符串拷贝;memcpy是通用型的拷贝,并且指定拷贝长度。
两者都要有返回值,并且返回值是目的地址指针
strcpy一般会覆盖,即使要复制的长度小于要复制过去的字符串。而memcpy不是。