深度剖析strcpy与memcpy

1 strcpy

1.1 strcpy的功能

用于将字符串从一个地方拷贝到另外一个地方。

1.2 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;

}

1.3需要特别注意的地方:

1.3.1 为什么要有函数返回值,并且返回值类型为char *?

答:首先必须要有返回值,因为字符串拷贝并不一定成功,比如传递的参数有问题,那么就必须通过返回特定的值进行查错;其次,拷贝成功后也要有返回值,肯定不应该是返回源地址值,因为它始终没有变过,返回它毫无意义。返回目的地址才是最合理的,因为把字符串从一个地方(src指向的地方)拷贝到另外一个地方(dst指向的地方)后接下来一般都会访问dst指向的地方,那么把dst的值返回给另外一个指针变量岂不是更加合理,例如:

char table[100];

char *buf = strcpy(table,"shenzhen");

此后就可以通过buf来访问table了。

1.3.2 为什么函数列表的第二个形式参数要用const修饰?

答:用const修饰就可以阻止src指向的区域被有意无意修改,const修饰*src,即修饰src指向的区域,所以对该区域进行写保护。

1.3.3 为什么要进行参数合法性检查?为什么不写成if((!dst)||(!src))?

答:①如果src的值为NULL,那么就会把一个非法区域的数据拷贝到dst指向的缓冲区中,而这很容易造成内存越界(因为很有可能很晚才遇到"/0"标记符或者无法遇到"/0"标记符);如果dst的值为NULL,那么就相当于把一串数据拷贝到一些非法区域,从而造成系统崩溃。②因为dst和src类型为char*,并不是BOOL类型,虽然if((!dst)||(!src))可以进行从char*到BOOL的隐形类型转换,但是这相当于把可靠性交给了第三方去维护,显然不是一个合格程序员的素养。

1.3.4 为什么while循环里面要判断!="/0"?为什么while循环不写成while (*strSrc!='\0') *dst++=*src++;?

答:①字符串都是以"/0"作为结束标志的,即便你写一个字符串"shenzhen",系统也会自动在结尾增加"/0",只是你看不到而已。②这样写就会导致字符串的"/0"无法拷贝到目的区域,这是不行的。

1.4 该函数有什么缺陷

①如果你传递进来的src指向的不是字符串,而是其他空间,那么会很容易造成内存越界。比如

char table1[10];

int table2[11]={1,2,3,4,5,6,7,8,9,10,11}

strcpy(&table1,&table2);

由于table2中存放的并不是字符串,因此在程序检测到"/0"这个字符串结束符之前,它会继续将table2中的数据拷贝到table1中,从而导致内存越界。

1.5 总结

一个简单的函数的编写足以窥视一个程序员的水准。函数功能主体设计固然很重要,但是函数返回值的设计、函数参数的安排、参数关键字的修饰(比如const、volatile等等)以及入口参数合法性检查,这些都是不是细节问题,而同样是函数主体的一部分,有时甚至更为关键。

 

2 memcpy

2.1 memcpy的函数功能

用于将指定长度的数据从一个地方拷贝到另外一个地方

2.2 memcpy函数的C语言源码:

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;

}

2.3 需要注意的地方

①函数返回值为什么是void *?

答:由于memcpy拷贝的数据并不限于字符串,理论上可以是指向任何类型的数据指针,因此这里设计为void *类型。

②函数形式参数为什么是void *?

答:memcpy拷贝的数据可以是任何类型的数据,所以这里采用void *类型。

3 strcpy和memcpy对比

3.1 strcpy只用于字符串拷贝,并且是任意长度的字符串拷贝;memcpy是通用型的拷贝,并且指定拷贝长度。

3.2 两者都要有返回值,并且返回值是目的地址指针

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值