strcpy的实现疑惑

fairchild811 2009-03-13 11:03:25
关于strcpy的实现,有人说:

/* the emplementation in VC++ */

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

{

char* tmp = dest;



while (*tmp++ = *src++)

;



return dest;

}



/* the emplementation in Linux */

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

{

char* tmp = dest;



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

;



return dest;

}


同时,也有人说:
Linux 下的定义是这样的:
/usr/lib/string.h


string.h:

char *strcpy (char *__restrict __dest, __const char *__restrict __src)

__THROW;


/usr/src/linux-2.6.0-test3/lib/string.c


/**

* strcpy - Copy a %NUL terminated string

* @dest: Where to copy the string to

* @src: Where to copy the string from

*/

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

{

char *tmp = dest;



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

/* nothing */;

return tmp;

}

还有:

char *strcpy(char *strDest,const char *strSrc)
{
assert((strDest!=NULL)&&(strSrc !=NULL))
char *address = strDest;
while((*strDest++ = *strSrc)!='\0')
NULL;
return address;
}这个好像是什么高质量C++什么的

请问,到底哪个才是正确的呢,是返回临时定义的指针还是返回参数中的destination str,为什么?
还有到底需要不要判断source和destination是不是NULL,不需要的理由是底层函数没必要进行这种判断
如果判断是用NULL还是用NULL,据说Bjarne Stroustrup本人是不赞成用NULL的。
...全文
413 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
feng4206yu 2009-03-14
  • 打赏
  • 举报
回复
1.关于指针返回,在这里返回原参数和局部变量都可以,因为都只是指向一个地址值....
2.判断是否用NULL或者'\0',这NULL一般都是表示该指针是否存在指向...'\0'表示字符串的结尾...在你说的c++的实现中,的确好像没判断char* dest是否存在指向,但是这个一般没有必要,需要程序员自己来保证..但是关于字符串的结尾的确都是判断了的while (*tmp++ = *sr++);当碰到字符串结尾是*temp = *str返回0,然后循环结束..这个和while ((*dest++ = *src++) != '\0')其实是一个道理...
3.所以高质量c++那个算是比较常规而且较易于接受的版本,先判断字符指针是否有分配内存,然后判断字符串结束符...
zhan1094 2009-03-14
  • 打赏
  • 举报
回复
学习了~~
brookmill 2009-03-14
  • 打赏
  • 举报
回复
mark
oyljerry 2009-03-14
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 fairchild811 的回复:]
好像不判断是否为空就是ls说的整个意思,所以好像除了assert的那个实现方式

其他几个方式都没有检查

我觉得既然VC和linux的实现都没有检查,一定有他的道理吧,不至于是那些niu人忘了吧:)
[/Quote]
老代码了,可能没有做这些,可以查看一下strcpy_s等security API是否改进了
fairchild811 2009-03-14
  • 打赏
  • 举报
回复
好像不判断是否为空就是ls说的整个意思,所以好像除了assert的那个实现方式

其他几个方式都没有检查

我觉得既然VC和linux的实现都没有检查,一定有他的道理吧,不至于是那些niu人忘了吧:)
野男孩 2009-03-14
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 sagegz 的回复:]
引用 21 楼 coding_hello 的回复:
都是正确的。标准库不去判断是否输入的指针是否为空,我认为没什么不对。

传入的指针不为空可以由调用者来保证。

那调用者要是忘了呢?所以还是应该在函数里判断指针是否为空.
[/Quote]

调用者要是忘了,那就出异常了呗。谁让调用者不检查的。实际上strcpy内部做这个检查也没啥用,就算知道是NULL指针,那么返回个NULL指针有啥用?反正调用者也不检查。
ydlchina 2009-03-14
  • 打赏
  • 举报
回复
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘\0’ );
  return address;
}
//一般有过面试的都会知道
sagegz 2009-03-14
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 coding_hello 的回复:]
都是正确的。标准库不去判断是否输入的指针是否为空,我认为没什么不对。

传入的指针不为空可以由调用者来保证。
[/Quote]
那调用者要是忘了呢?所以还是应该在函数里判断指针是否为空.
野男孩 2009-03-14
  • 打赏
  • 举报
回复
都是正确的。标准库不去判断是否输入的指针是否为空,我认为没什么不对。

传入的指针不为空可以由调用者来保证。
aaaa3105563 2009-03-14
  • 打赏
  • 举报
回复
顶上
zhaohongbo83 2009-03-14
  • 打赏
  • 举报
回复
mark
yangch_nhcmo 2009-03-13
  • 打赏
  • 举报
回复
因为返回首地址,但其在运算中有进行自增操作,所以定义一个临时变量来保存其首地址,以便返回.
hjjdebug 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 fairchild811 的帖子:]
请问,到底哪个才是正确的呢,是返回临时定义的指针还是返回参数中的destination str,为什么?
还有到底需要不要判断source和destination是不是NULL,不需要的理由是底层函数没必要进行这种判断
如果判断是用NULL还是用NULL,据说Bjarne Stroustrup本人是不赞成用NULL的。
[/Quote]
1. 仔细看一下程序,都是正确的。它们都是返回最初传来的destination 的地址。只不过在形式上,
有的用了return tmp, 有的用了return dest. 你可以调试看一下结果。
2.除C++, 其它程序都没有判断src 或 dst 是否为NULL, 记住, NULL 指针数值就是0. 如果你向0地址
读写数据,会引起系统异常,显示一个unhandle exception 信息窗。点确认后程序关闭

3.c++ 用assert 宏来断言src 及 dst 为非零,这是一种调试手段,在debug 版本中,给你一个选择是
终止程序,重来一次还是忽略错误继续运行。用途不大。
在release 版, 断言语句将被自动抹去,等价于没有。

所以说,上面几种写法完全是一样的。
lingyin55 2009-03-13
  • 打赏
  • 举报
回复
有几个问题

1、返回的都是首地址,一个是把保存的副本返回,原先的指针移动,一个是原先的返回,副本移动,但都是一样的啊。
2、/* the emplementation in VC++ */ 没有检查输入的两个指针是否有效。
3、/* the emplementation in VC++ */ 没有检查源字符串是否以NULL结尾。
4、没有检查目标指针的空间是否大于等于原字符串的空间。

除了第1个,其余的都应该是要求由使用者去实现的。所以没有说哪一个是正确的,各个编译器实现的机制不一样,但是使用前最好对可能出现异常的地方进行判断,因为这也是使用strncpy经常出现异常的原因。至于你说的有没有什么更底层的函数去帮助判断,比如说是否为空,我觉得应该没有了。这么一个简单的功能,没有必要还分出那么多个函数去实现。
chin_chen 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 fairchild811 的回复:]
呵呵,我知道保存首地址,2楼的和我说的方法不一样。

其实最主要的就是return tmp和return dest有没有区别。因为一个是参数传递,一个是局部定义的。

另外assert时是==NULL还是==0
[/Quote]
另外assert时是==NULL还是==0,一般的话两者一样的。
fairchild811 2009-03-13
  • 打赏
  • 举报
回复
还有,如果是return dest的话,函数返回前tmp如果不设置为NULL,是不是会成为野指针
fairchild811 2009-03-13
  • 打赏
  • 举报
回复
呵呵,我知道保存首地址,2楼的和我说的方法不一样。

其实最主要的就是return tmp和return dest有没有区别。因为一个是参数传递,一个是局部定义的。

另外assert时是==NULL还是==0
  • 打赏
  • 举报
回复
请问,到底哪个才是正确的呢,是返回临时定义的指针还是返回参数中的destination str,为什么?
还有到底需要不要判断source和destination是不是NULL,不需要的理由是底层函数没必要进行这种判断
如果判断是用NULL还是用NULL,据说Bjarne Stroustrup本人是不赞成用NULL的。

返回临时定义的指针还是返回参数中的destination str,这2者没有太大区别啊,得到的结果都是一样的。
strcpy是通过判断是否到src尾端的'\n'来实现的,是C标准函数的原则。
xyzxuyanzhong 2009-03-13
  • 打赏
  • 举报
回复
strcpy可以拷贝
chin_chen 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 fairchild811 的回复:]
return tmp是因为如果不return他就没法在以后释放他?

谢谢2楼的,这么快回复
[/Quote]这里不需要delete啊,至于为啥要返回char*,可能是方便其它用途吧,就是调用这个函数后,可以直接访问修改后的那块内存的起始地址了啊。
加载更多回复(8)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧