C语言程序设计中strcpy,C语言中strcpy函数
讲解比较的详细!
已知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函数相关推荐
- exit在c语言里的作用,C语言中exit函数的使用
exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调 ...
- c语言scanf中 作用,c语言中scanf的用法
c语言中scanf的用法的用法你知道吗?下面小编就跟你们详细介绍下c语言中scanf的用法的用法,希望对你们有用. c语言中scanf的用法的用法如下: printf和scan函数的使用方法 一 pr ...
- c语言数组中define,c语言中#define的用法
c语言中#define的用法 C语言中,可以用 #define 定义一个标识符来表示一个常量.其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了. 预编译又叫预处理.预编译 ...
- c语言ftell的作用,C语言中ftell函数的使用方法
在C语言中,ftell函数用来返回回当前文件指针的位置.其定义在stdio.h头文件中.具体介绍如下: 函数原型:long ftell(FILE *fp); 是否是标准函数:是 函数功能:返回当前文件 ...
- c语言switch scanf语句,C语言中scanf函数与switch语句
----------------switch---------------- 1)使用格式 switch(表达式){ case 常量表达式1: 语句1; case 常量表达式2: 语句2; ... c ...
- c语言rand的参数,C语言中rand()函数的用法
一.rand() rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的. rand()会返回一个范围在0到RAN ...
- c语言 strcpy原型,浅谈C语言中strcpy,strcmp,strlen,strcat函数原型
实例如下: //strcat(dest,src)把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0' char *strcat(char * strDest, cons ...
- c语言 strcpy作用,c语言中strcpy的用法
c语言中strcpy的用法的用法你知道吗?下面小编就跟你们详细介绍下c语言中strcpy的用法的用法,希望对你们有用. c语言中strcpy的用法的用法如下: strcpy原型声明:extern ch ...
- c语言中 调用函数除函数名外,【单选题】在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分)
A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值...
[单选题]在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值 更多相关问题 下列关于IMOECDIS性能标 ...
最新文章
- spring读取配置文件的几种方式
- JQ用变量关联input name
- QT手动moc问题:virtual struct QMetaObject const * __thiscall Widget::metaObject
- java并发编程系列-内存模型基础
- java模拟国际象棋游戏_java国际象棋小游戏
- bat命令 修改ini文件内容_Linux文件内容查看相关命令
- 本科计算机学的都是皮毛吗,教唆高考生千万别学计算机专业,为什么相当于断人前途?...
- VTK:几何对象之CylinderExample
- 为什么要设置环境变量,环境变量有什么用?
- 【176天】黑马程序员27天视频学习笔记【Day11-上】
- 空值替换为0_Excel查找、替换和定位
- 小男孩与苹果树(翻译)(06年10月)
- 成语接龙Java代码实现
- ubuntu 如何关闭笔记本触摸板
- mysql 模糊查找表名
- mysql的主句与从句_where there is a will,there is a way是什么意思 MYsql 三张表 我能写 where a.id=b.id=c.id 还是一......
- 基恩士KV7500,KV8000轴控制FB模板,直接可以拿来用,使基恩士编程也随心所欲
- 给一个数组[a1,a2,a3....an],要求出令ai-aj有最大值,其中i<=j,时间复杂度尽可能小 ```
- [Unity实战]仅用2步-虚拟相机Cinemachine简易使用
- 神策数据 方正证券发布《2022 证券行业行为数据根基建设白皮书》
热门文章
- 基于stm32f429的手写识别_【连载】STM32开发指南--第五十一章 手写识别实验
- CollectionUtils取交集、并集和差集
- 我获得了CSDN的微软博客达人优秀奖
- 中国的数字化转型案例简析 China’s digital transformation
- matlab求解常系数线性差分方程,用matlab实现线性常系数差分方程的求解
- adjtimex使用
- 数值分析——数值积分(Newton-Cotes、复化求积、Gauss求积、正交多项式Gauss)
- 修改电脑dns服务器地址
- 看linux源码到什么哎程度,Linux 查看命令源码
- 卖期权的时候,我们在卖什么?