zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    第三次冲刺
    [操作系统]实验四
    第二个冲刺5.0
    第二个冲刺
    学术诚信与职业道德--个人感想
    软件工程——sprint 1回顾总结
    [读书笔记]
    sprint5.0
    [操作系统]3.0
    学习进度条
  • 原文地址:https://www.cnblogs.com/yancey/p/3388725.html
Copyright © 2011-2022 走看看