C语言标准库函数strcpy,把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间

已知strcpy函数的原型是:

char *strcpy(char *dst, const char *src);

  1. 实现strcpy函数
  2. 解释为什么要返回char *
  3. 假如考虑dst和src内存重叠的情况,strcpy该怎么实现

1.strcpy的实现代码

char * strcpy(char *dst,const char *src)   //[1]
{
assert(dst != NULL && src != NULL); //[2] char *ret = dst; //[3] while ((*dst++=*src++)!='\0'); //[4] return ret;
}

[1]const修饰

源字符串参数用const修饰,防止修改源字符串。

[2]空指针检查

(A)不检查指针的有效性,说明答题者不注重代码的健壮性。

(B)检查指针的有效性时使用assert(!dst && !src);

char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。

(C)检查指针的有效性时使用assert(dst != 0 && src != 0);

直接使用常量(如本例中的0)会减少程序的可维护性。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。

[3]返回目标地址

(A)忘记保存原始的strdstt值。

[4]'\0'

(A)循环写成while (*dst++=*src++);明显是错误的。

(B)循环写成while (*src!='\0') *dst++=*src++;

循环体结束后,dst字符串的末尾没有正确地加上'\0'。

2.为什么要返回char *?

返回dst的原始值使函数能够支持链式表达式。

链式表达式的形式如:

int l=strlen(strcpy(strA,strB));

又如:

char * strA=strcpy(new char[10],strB);

返回strSrc的原始值是错误的。

其一,源字符串肯定是已知的,返回它没有意义。

其二,不能支持形如第二例的表达式。

其三,把const char *作为char *返回,类型不符,编译报错。

3.假如考虑dst和src内存重叠的情况,strcpy该怎么实现

char s[10]="hello";

strcpy(s, s+1); //应返回ello,

//strcpy(s+1, s); //应返回hhello,但实际会报错,因为dst与src重叠了,把'\0'覆盖了

所谓重叠,就是src未处理的部分已经被dst给覆盖了,只有一种情况:src<=dst<=src+strlen(src)

C函数memcpy自带内存重叠检测功能,下面给出memcpy的实现my_memcpy。

char * strcpy(char *dst,const char *src)
{
assert(dst != NULL && src != NULL); char *ret = dst; my_memcpy(dst, src, strlen(src)+1); return ret;
}

my_memcpy的实现如下

char *my_memcpy(char *dst, const char* src, int cnt)
{
assert(dst != NULL && src != NULL); char *ret = dst; if (dst >= src && dst <= src+cnt-1) //内存重叠,从高地址开始复制
{
dst = dst+cnt-1;
src = src+cnt-1;
while (cnt--)
*dst-- = *src--;
}
else //正常情况,从低地址开始复制
{
while (cnt--)
*dst++ = *src++;
} return ret;
}

strcpy c标准库函数的更多相关文章

  1. C89标准库函数手册(待整理)

    http://zh.cppreference.com/w/c 前言 ANSI C(C89)标准库函数共有15个头文件.这15个头文件分别为: 1.<assert.h>            ...

  2. C++ - 常用的标准库函数

      写在前面 C++是一门博大精深的语言,也是最难学的一门编程语言,每一位励志学好C++的程序员都需要从基本功开始,稳扎稳打. 自从1998年C++ standard定案以后,C++程序库便有了大幅扩 ...

  3. C语言中最常用标准库函数

    标准头文件包括: <asset.h>      <ctype.h>       <errno.h>       <float.h> <limits ...

  4. C89标准库函数手册

    http://zh.cppreference.com/w/c 前言 ANSI C(C89)标准库函数共有15个头文件.这15个头文件分别为: 1.<assert.h>            ...

  5. C语言中最常用的标准库函数

    标准头文件包括: <asset.h>      <ctype.h>       <errno.h>       <float.h> <limits ...

  6. 标准库函数atoi的实现

    标准库函数atoi用于将字符串类型的数据转换为整形数据:在转换过程中要考虑空指针.空字符串"".正负号,溢出等情况 这里是将字符串str转换为32位整型,其正数的最值为0x7FFF ...

  7. C语言提供了几个标准库函数 itoa() atoi()

    C语言提供了几个标准库函数C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串.以下是用itoa()函数将整数转换为字符串的一个例子: # include <s ...

  8. 范围for语句 && 列表初始值&& 标准库函数begin和end

    范围for语句: 引入的意义:简化传统for的编写,主要用于遍历给定序列中的每个元素并对序列中的每个值执行某种操作,其语法形式是: for( 声明: 给定序列) { 执行的操作. } 其中,“给定序列 ...

  9. UC编程:通过fwrite()和write()比较标准库函数和系统调用的速度

    fwrte是C标准库中提供的函数,是对write函数的扩展与封装,write则是Unix系统提供的函数.按照常理来讲,系统调用肯定比使用库快的多,但是事实正好相反 Why?原因就在于缓冲的问题,fwi ...

随机推荐

  1. IOS应用

    下面是这个类的一些功能: 1.设置icon上的数字图标 //设置主界面icon上的数字图标,在2.0中引进, 缺省为0 [UIApplicationsharedApplication].applica ...

  2. Redis学习笔记(二)字符串进阶

    1.增减操作 字符串可以储存字节串.整数.浮点数三种类型的值,如果值无法被解释为十进制的整数或浮点数,那么对此值进行增减操作会返回错误,如果对一个不存在的或者保存了空串的键进行增减操作,Redis将当 ...

  3. Java JDK装配置

     1- 介绍 本文章介绍JAVA开发环境安装是基于:  Java8(JDK8) 2- 下载JDK http://www.oracle.com/technetwork/java/javase/dow ...

  4. 看Spring Data如何简化数据操作

    Spring Data 概述 Spring Data 用于简化数据库访问,支持NoSQL 和 关系数据存储,其主要目标是使数据库的访问变得方便快捷. SpringData 项目所支持 NoSQL 存储 ...

  5. emacs - GNU Emacs

    总览 (SYNOPSIS) emacs [ command-line switches ] [ files ... ] 描述 (DESCRIPTION) GNU Emacs 是 Emacs 的 一个 ...

  6. Mac下Apache服务器的初步搭建

    回送地址  127.0.0.1(localhost)  ping 这个地址可以检测网卡是否正常 ping 本地地址如果不正常说明网线挂了   // 启动 sudo apachectl -k start ...

  7. Python自动化测试框架——概述

    #使用import import unittest #测试用例TestCase ''' 一个测试用例时一个完整的测试流程,包括了环境准备SetUp,测试执行Run,测试环境还原TearDown 一个测 ...

  8. 查询SYS_ORG_TB树的层级

    WITH N(SYS_ORG_ID,SYS_ORG_NAME,LEVEL) AS( AS LEVEL FROM SYS_ORG_TB WHERE SYS_ORG_UPID IS NULL UNION ...

  9. 如何用纯 CSS 创作一种有削铁如泥感觉的菜单导航特效

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/XqYroe 可交互视频教 ...

  10. 条款14:在资源管理类中心copying行为(Think carefully about copying behavior in resource-manage classes)

    NOTE: 1.复制RAII 对象必须一并赋值它所管理的资源,所以资源的copying行为决定RAII对象的copying行为. 2.普遍而常见的RAII class copying 行为是: 抑制c ...