strcpy实现 处理地址重叠,返回值问题

strcpy的主要功能就是将原串拷贝到目标,一个比较简单的实现版本为

 void strcpy(char * dest, char * src) {
      assert(src!=NULL);
      assert(dest!=NULL);
      char *ret = dest
      while((*ret) = (*src) && (*src)!=‘0’) {
           src++;
           ret++;
      }
 }

比较常用的实现是以上那个版本,那么这个函数其实是由很多问题的,我们进行第
问题1、将src++和dest++写在while循环的条件式里面,这样做的好处是有些编译器会对这种操作做些优化,而且编译出来的汇编码也会简短很多
问题2、传入的src指针我们不需要更改它的位置,那么它应该为const

 void strcpy(char* dest, const char* src) {
      assert(src!=NULL);
      assert(dest!=NULL);
      char *ret = dest;
      while((*ret++t) = (*src++) && (*src)!=‘0’) {
      }
 }

问题3、没有处理src和dest地址出现交叠的情况,当&src<&dest时,按照如上代码就会出息问题,比如:src=“abcd” &src=0001,&dest=0002
第一次循环地址为0002的值被赋值为a,那么也就是说src中第二个字符b已经被更改为a,那么第二次循环时dest的值就会变成“aa”。解决这个问题的办法就是需要从后向前拷贝,那么代码就会变成

 void strcpy(char* dest, const char* src) {
      assert(src!=NULL);
      assert(dest!=NULL);
      char *ret = dest;
      if (src < dest)
           while((*ret++t) = (*src++) && (*src)!=‘0’) {
           }
      else if {
           int len = strlen(src);
           while (len—) {
                *(ret + len) = *(src + len);
           }
      }
      else  {}
 }

问题4、上面的代码看起来是安全的了,但还有一个返回值的问题,的确以void作为返回值没有什么问题,但如果将dest的指针作为返回值有一个作用:生成链式表达式。
比如这样的代码:

int len = strlen(strcpy(dest, “abcde"));

但如果没有返回值,那么就要写成这样:
 char * dest;
 strcpy(dest, "abcd");
 int len = strlen(dest);

好吧,多写了一行代码。。。。其实我也没有理解链式表达式最大的优势在哪里,如果只是为了减少一行代码,我个人觉得没有太多必要,如果有哪位前辈晓得可以指点一二,不胜感激。

个人博客:http://www.yancey.info/?p=112

原文地址:https://www.cnblogs.com/yancey/p/3388725.html