Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 581|回复: 0

开发交流:百度面试题之strcpy

[复制链接]

该用户从未签到

发表于 2011-10-24 10:31:16 | 显示全部楼层 |阅读模式
各大公司尤其百度、腾讯等一线公司都喜欢问这个题,我想了想,可能这个题特别能看出一个人的逻辑思维能力、反应能力、考虑问题是否周到、写代码是否规范优雅,所以,这个题大家好好看看。不要觉得这个很简单,一问你,你就知道,其实你学的还不行。里面涉及到问题很多的。

字符串拷贝函数strcpy写法



// CppReference.cpp : 定义控制台应用程序的入口点。

//#include "stdafx.h"

using namespace std;/*

* 说明:字符串拷贝版本1

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错或者有重叠,无定义

* 异常:可能出现字符串溢出,即dest所占空间不如src所占空间大。

*/

char *strcpy_v1(char *dest , const char *src)

{

//调试时,使用断言,入口检测

assert( (dest!=NULL) && (src!=NULL) );



//注意这里的内存指向参数dest所在的内存,不是栈内存,因而可以在函数中返回

char *to = dest;



//主要操作在while条件中完成

while( (*dest++ = *src++)!='\0')

{

NULL;

}



//返回拷贝字符串首地址,方便连缀,比如strlen(strcpy(dest,"hello"))

return to;

}/*

* 说明:字符串拷贝版本2

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。

*/

char *strcpy_v2(char *dest , const char *src)

{

char *d = dest;

char c;



while((c=*src++) != '\0')

{

*(dest++)=c;

}



*dest='\0';



return d;

}/*

* 说明:字符串拷贝版本2(你能找出错误的原因吗)

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。

*/

char *strcpy_v2_error(char *dest , const char *src)

{

char *d = dest;

char c;



while((c=*src++) != '\0')

{

*(d++)=c;

}



*d='\0';



return d;

}

/*

* 说明:字符串拷贝版本3

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。

*/

char *strcpy_v3(char *dest , const char *src)

{

char *d = dest;

char c;



while(*src)

*dest++ = *src++;



*dest='\0';



return d;

}/*

* 说明:字符串拷贝版本4

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。

*/

char *strcpy_v4(char *dest , const char *src)

{

char *d = dest;

char c;



while( (*dest = *src)!='\0')

{

src++;

dest++;

}



*dest='\0';



return d;

}/*

* 说明:字符串拷贝版本5

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。restrict关键字限定字符串不能重叠。

*/

char *strcpy_v5(char* _restrict dest , const char* _restrict src)

{

char *d = dest;

char c;



while( (*dest = *src)!='\0')

{

src++;

dest++;

}



*dest='\0';



return d;

}/*

* 说明:字符串拷贝版本6

* 参数:dest目标地址,src源地址

* 返回:返回拷贝好的地址;如果出错,无定义

* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。restrict关键字限定字符串不能重叠。

*/

char *strcpy_v6(char* _restrict dest , const char* _restrict src)

{

char *d = dest;

char c;



while(*dest++=*src++);

return d;

}int _tmain(int argc, _TCHAR* argv[])

{

char buf[512];



char *buf2 = (char *)calloc(50,sizeof(char));



char *buf3 = (char *)malloc(50*sizeof(char));



char *buf5 = (char *)malloc(50*sizeof(char));



char *buf6 = (char *)malloc(50*sizeof(char));



printf("using strcpy_v1,the string 'Hello,World'\'s length is : %d\n",strlen(strcpy_v1(buf,"Hello,World")));



printf("using strcpy_v2,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v2(buf2,"This is the best age")));



printf("using strcpy_v2,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v2_error(buf2,"This is the best age")));



printf("using strcpy_v3,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v3(buf3,"This is the best age")));



printf("using strcpy_v5,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v5(buf5,"This is the best age")));



printf("using strcpy_v6,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v6(buf6,"This is the best age")));



system("pause");



return 0;

}







请问下面这个strcpy 函数的功能是把字符串t 复制到串s中

strcpy(char *s,char *t)

{ while(*s++ = *t++);

}



是对的,while(*s++=*t++);里面的语句是先执行*t=*t,再s++,t++,当达到'\0'时候,也复制进去了,所以是对的

这种写法不但正确而且非常高效!



(1)while(condition){//循环体}当condition为非零时,就进入循环体,此例循环体是一句空语句,即什么都不做;

(2)我们知道字符串结束符为'\0'其ASCII值为0,我们来检查一下condition语句:

*s++ = *t++;

// 分解一下:

1)首先*s = *t (把指针t所指内存赋值到s所指内存,由于指针类型为char,则系统每次会取出sizeof(char)个字节大小的内存进行赋值操作,s所指原内存被覆盖掉,而t所指内容保持不变;

2)condition语句最后的值为指针s所指的内存内容;

3)while(condition)//while开始判断condition的值,若为零则循环结束,否则进入循环体;

4)然后s++,t++指针移动sizeof(char)个字节,同时指向下一个内存单元;





显然:只有当condition(即指针s所指内容)为零时循环结束,我们可以看到只有当字符串指针t指向字符串结束符'\0'时(其ASCII码为0),通过赋值语句赋给指针s所指内存时,s的所指内容为'\0'(编译器看到condition就是0),循环结束!而此时,字符串复制工作也正好结束。非常完美!



通过分析strcpy的实现,那么在使用中需要注意的是:

strcpy函数把源字符串包含字符串结束符'\0'都一个不漏地拷贝到目标内存中了,那么分配给目标内存的大小除了包含有效字符串长度时,还要多加一个sizeof(char)的内存大小来存放字符串结束符'\0',见如下的示例:

char* t = {"Hello World"};

char* s = new char[strlen(t) + 1]; // strlen(t)返回有效字符串长度

strcpy(s, t);

// 使用s

delete s;



另外个人认为,这个函数应该是这样的参数才最为合理:

strcpy(char* s, const char* t); // 即源字符串指针所指内容应该为只读





(*s++ = *t++);

这个是赋值不是 (*s++ == *t++);

当赋值语句的返回值是 *t,若 *t返回为0,则退出循环?



最简单的写法:

char *strcpy(char *s1,char *s2)

{

while(*s2++ = *s1++);

return s2;

}
复制代码


字符串拷贝函数.docx (17.43 KB, 下载次数: 0, 售价: 1 下载豆)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 05:36 , Processed in 0.338164 second(s), 34 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表