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

  • 相关阅读:
    使用 GitHub, Jekyll 打造自己的免费独立博客
    如何解决数据科学计数法在数据库中的显示
    RDF
    C# 在 4.0 以后一共有3种创建线程的方式
    C#多线程
    1、框架概述
    3、IDEA 中使用 Maven
    2、Maven 核心概念
    1、Maven 概述
    JDK动态代理
  • 原文地址:https://www.cnblogs.com/yancey/p/3388725.html
Copyright © 2011-2022 走看看