讲解比较的详细!

已知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 Arguments"; //[2]

//assert((strDest!=NULL) && (strSrc !=NULL));

char* strDestCopy = strDest; //[3]

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

;

return strDestCopy;

}

[1]

(A)不检查指针的有效性,说明设计者不注重程序的健壮性

(B)检查指针的有效性时使用((!strDest) || (!strSrc))或(!(strDest && strSrc)),说明对C语言中

类型隐式转换没有深刻认识,在本例中char*转换为bool即是类型隐式转换,这种功能虽然灵活,但

是更多的是导致出错概率的增大和维护成本的增高

(C) 检查指针的有效性时使用((strDest==0)||(strSrc==0))说明答题者不知道使用常量的好处。直接使用字面常量(如本例中的0)会

减少程序的可维护性。0虽然简单,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内含逻辑

错误,很难排除。而使用NULL 代替0,如果出现拼写错误,编译器就会检查出来。

[2]

(A)return new string("Invalid arguments");,说明答题者根本不知道返回值得用途,并且它对内存泄露也没有警惕心,从函数体中

返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内存,这

导致内存泄露

(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 *返回,类型不符,编译报错。

1.引言

本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论

坛,部分试题解答也参考了网友的意见。

许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在

技术上究竟达到了怎样的程 度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分

中的2分。读者可从本文看到strcpy 函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏

捷的思维能力。

分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。

2.找错题

试题1:

void test1()

{

char string[10];

char* str1 = "0123456789";

strcpy( string, str1 );

}

试题2:

void test2()

{

char string[10], str1[10];

int i;

for(i=0; i<10; i++)

{

str1 = 'a';

}

strcpy( string, str1 );

}

试题3:

void test3(char* str1)

{

char string[10];

if( strlen( str1 ) <= 10 )

{

strcpy( string, str1 );

}

}

解答:

试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;

对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起

复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;

对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。

剖析:

考查对基本功的掌握:

(1)字符串以’\0’结尾;

(2)对数组越界把握的敏感度;

(3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

2分

void strcpy( char *strDest, char *strSrc )

{

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

4分

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

//将源字符串加const,表明其为输入参数,加2分

{

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

7分

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

{

//对源地址和目的地址加非0断言,加3分

assert( (strDest != NULL) && (strSrc != NULL) );

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

10分

//为了实现链式操作,将目的地址返回,加3分!

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

{

assert( (strDest != NULL) && (strSrc != NULL) );

char *address = strDest;

while( (*strDest++ = * strSrc++) != ‘\0’ );

return address;

}

C语言程序设计中strcpy,C语言中strcpy函数相关推荐

  1. exit在c语言里的作用,C语言中exit函数的使用

    exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调 ...

  2. c语言scanf中 作用,c语言中scanf的用法

    c语言中scanf的用法的用法你知道吗?下面小编就跟你们详细介绍下c语言中scanf的用法的用法,希望对你们有用. c语言中scanf的用法的用法如下: printf和scan函数的使用方法 一 pr ...

  3. c语言数组中define,c语言中#define的用法

    c语言中#define的用法 C语言中,可以用 #define 定义一个标识符来表示一个常量.其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了. 预编译又叫预处理.预编译 ...

  4. c语言ftell的作用,C语言中ftell函数的使用方法

    在C语言中,ftell函数用来返回回当前文件指针的位置.其定义在stdio.h头文件中.具体介绍如下: 函数原型:long ftell(FILE *fp); 是否是标准函数:是 函数功能:返回当前文件 ...

  5. c语言switch scanf语句,C语言中scanf函数与switch语句

    ----------------switch---------------- 1)使用格式 switch(表达式){ case 常量表达式1: 语句1; case 常量表达式2: 语句2; ... c ...

  6. c语言rand的参数,C语言中rand()函数的用法

    一.rand() rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的. rand()会返回一个范围在0到RAN ...

  7. c语言 strcpy原型,浅谈C语言中strcpy,strcmp,strlen,strcat函数原型

    实例如下: //strcat(dest,src)把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0' char *strcat(char * strDest, cons ...

  8. c语言 strcpy作用,c语言中strcpy的用法

    c语言中strcpy的用法的用法你知道吗?下面小编就跟你们详细介绍下c语言中strcpy的用法的用法,希望对你们有用. c语言中strcpy的用法的用法如下: strcpy原型声明:extern ch ...

  9. c语言中 调用函数除函数名外,【单选题】在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值...

    [单选题]在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值 更多相关问题 下列关于IMOECDIS性能标 ...

最新文章

  1. spring读取配置文件的几种方式
  2. JQ用变量关联input name
  3. QT手动moc问题:virtual struct QMetaObject const * __thiscall Widget::metaObject
  4. java并发编程系列-内存模型基础
  5. java模拟国际象棋游戏_java国际象棋小游戏
  6. bat命令 修改ini文件内容_Linux文件内容查看相关命令
  7. 本科计算机学的都是皮毛吗,教唆高考生千万别学计算机专业,为什么相当于断人前途?...
  8. VTK:几何对象之CylinderExample
  9. 为什么要设置环境变量,环境变量有什么用?
  10. 【176天】黑马程序员27天视频学习笔记【Day11-上】
  11. 空值替换为0_Excel查找、替换和定位
  12. 小男孩与苹果树(翻译)(06年10月)
  13. 成语接龙Java代码实现
  14. ubuntu 如何关闭笔记本触摸板
  15. mysql 模糊查找表名
  16. mysql的主句与从句_where there is a will,there is a way是什么意思 MYsql 三张表 我能写 where a.id=b.id=c.id 还是一......
  17. 基恩士KV7500,KV8000轴控制FB模板,直接可以拿来用,使基恩士编程也随心所欲
  18. 给一个数组[a1,a2,a3....an],要求出令ai-aj有最大值,其中i<=j,时间复杂度尽可能小 ```
  19. [Unity实战]仅用2步-虚拟相机Cinemachine简易使用
  20. 神策数据 方正证券发布《2022 证券行业行为数据根基建设白皮书》

热门文章

  1. 基于stm32f429的手写识别_【连载】STM32开发指南--第五十一章 手写识别实验
  2. CollectionUtils取交集、并集和差集
  3. 我获得了CSDN的微软博客达人优秀奖
  4. 中国的数字化转型案例简析 China’s digital transformation
  5. matlab求解常系数线性差分方程,用matlab实现线性常系数差分方程的求解
  6. adjtimex使用
  7. 数值分析——数值积分(Newton-Cotes、复化求积、Gauss求积、正交多项式Gauss)
  8. 修改电脑dns服务器地址
  9. 看linux源码到什么哎程度,Linux 查看命令源码
  10. 卖期权的时候,我们在卖什么?