C++中strcpy函数的实现

 更新时间:2015年10月04日 14:01:11   投稿:hebedich  
strncpy这个可以指定拷贝字符的长度,指定源地址,目标地址,还有需要拷贝的字符的长度; strcpy只能传入两个参数,只指定拷贝的起始地址跟目标地址,然后整体拷贝;

我们先来看个例子

char * strcpy(char * strDest,const char * strSrc) {
  if ((NULL==strDest) || (NULL==strSrc)) 
    throw "Invalid argument(s)";
  char * strDestCopy = strDest;
  while ((*strDestCopy++ = *strSrc++) != '\0');
  return strDest;
}

突然想到之前做过的一个试题

题目:
    已知strcpy函数的原型是:
        char * strcpy(char * strDest,const char * strSrc);
    1.不调用库函数,实现strcpy函数。
    2.解释为什么要返回char *。

    解说:
    1.strcpy的实现代码

    char * strcpy(char * strDest,const char * strSrc)

    {

        if ((strDest==NULL)||(strSrc==NULL)) //[1]

            throw "Invalid argument(s)"; //[2]

        char * strDestCopy=strDest; //[3]

        while ((*strDest++=*strSrc++)!='/0'); //[4]

        return strDestCopy;

    }

    错误的做法: 

    [1]
    (A)不检查指针的有效性,说明答题者不注重代码的健壮性。
    (B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。
    (C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使用常量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。 

    [2]
    (A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值的用途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内存,这导致内存泄漏。
    (B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。 

   [3]
    (A)忘记保存原始的strDest值,说明答题者逻辑思维不严密。
    [4]
    (A)循环写成while (*strDest++=*strSrc++);,同[1](B)。
    (B)循环写成while (*strSrc!='/0') *strDest++=*strSrc++;,说明答题者对边界条件的检查不力。循环体结束后,strDest字符串的末尾没有正确地加上'/0'。

    2.返回strDest的原始值使函数能够支持链式表达式,增加了函数的“附加值”。同样功能的函数,如果能合理地提高的可用性,自然就更加理想。
    链式表达式的形式如:
        int iLength=strlen(strcpy(strA,strB));
    又如:
        char * strA=strcpy(new char[10],strB);
    返回strSrc的原始值是错误的。其一,源字符串肯定是已知的,返回它没有意义。其二,不能支持形如第二例的表达式。其三,为了保护源字符串,形参用const限定strSrc所指的内容,把const char *作为char *返回,类型不符,编译报错。

相关文章

  • 一篇文章带你了解C语言的选择结构

    一篇文章带你了解C语言的选择结构

    这篇文章主要为大家介绍了C语言的选择结构,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • C语言指针入门的简单实例教程

    C语言指针入门的简单实例教程

    这篇文章主要给大家介绍了关于C语言指针入门的简单实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 详解C语言中index()函数和rindex()函数的用法

    详解C语言中index()函数和rindex()函数的用法

    这篇文章主要介绍了C语言中index()函数和rndex()函数的用法,是C语言入门学习中的基础知识,要的朋友可以参考下
    2015-08-08
  • 深入理解c/c++ 内存对齐

    深入理解c/c++ 内存对齐

    这篇文章主要介绍了c/c++ 内存对齐,有需要的朋友可以参考一下
    2014-01-01
  • C++中友元函数(friend)解析

    C++中友元函数(friend)解析

    这篇文章主要分享了C++友元函数讲解,C++提供了一种形式的访问权限,叫做友元,友元有三种,分别是友元函数、友元类和友元成员函数,下面将详细介绍该内容,需要的小伙伴可以参考一下
    2022-01-01
  • C语言八大排序之堆排序

    C语言八大排序之堆排序

    堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序
    2022-02-02
  • C语言数据结构系列篇二叉树的遍历

    C语言数据结构系列篇二叉树的遍历

    本章将会详细讲解二叉树遍历的四种方式,分别为前序遍历、中序遍历、后续遍历和层序遍历。在学习遍历之前,会先带大家回顾一下二叉树的基本概念
    2022-02-02
  • c语言判断是否素数程序代码

    c语言判断是否素数程序代码

    这篇文章主要介绍了c语言判断是否素数的方法和问题,大家参考使用吧
    2013-11-11
  • C++利用PCL点云库操作txt文件详解

    C++利用PCL点云库操作txt文件详解

    这篇文章主要为大家详细介绍了C++如何利用PCL点云库操作txt文件,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2024-01-01
  • C++超详细讲解逻辑操作符

    C++超详细讲解逻辑操作符

    在C语言中,逻辑运算符有&&、||、!;&&表示“与”的意思,需要两端的表达式的值都为true,该式的值才为true。||表示“或”的意思,两端的表达式的值只要有一端为true,该式的值就为true。!表示“非”的意思,将该式的真值换成相反的真值,即false和true互换
    2022-06-06

最新评论