关于strcpy,我在看 一个讨论的时候,说是 strcpy 为什么要返回 char* ,理由有 一个是提供相同的函数调用风格(string.h 大部分都是返回 char*),一个是为了 链式传递的编写(比如 printf( strcat( strcpy(str,"hello,") , "world\n") ); )。就像里面的观点一样,我认为返回一个char* ,不如返回一个 int(字符串长度),虽然反对者说 长度只是字符串的一个特性,不能代表字符串本。我同意的理由也就是3点:
1,在实际中,strcpy 的返回值,很少用到,链式的编写并不比 分开编写来的轻松,而且反而不利于调试,也大大降低了代码的可读性。
2,如果strcpy 返回 char* , 那么 要的到实际复制的字节数,在某些情况下,可能会变得相当困难,比如 char s1[] = "hello,world!"; char s2[] = "yes,my boss!"; strcpy((char*)s2 + 6 , s1); 此时, s1 和 s2 都已不是 原来的内容了,这个时候只能通过 strlen(s2 + 6) 来的到实际复制的字节数。
3,而且在大量使用 strcpy 的地方,返回 字符串长度也是能提高一些效率的(此时可以使用 strncpy了)。
说到 strncpy ,上次有个孩子,说你写个 strcpy 出来看看,于是我就写了,结果那个孩子说我写的不行,效率太差,我就奇怪了,大家都这样写,为啥我写的就不行呢,于是,那个孩子就给我贴了一段代码,说是 GCC 的源码,我一看,那个坑爹的,赫然就是 strncpy 的,而且有一个非常醒目的
RtlStringCchCopyNEx(OTL,这个是什么就不说了) 。那孩子说看看别人写的,一次就复制4字节。我于是兴趣缺缺的问了一下是什么编译器的源码,答曰 MinGW。
最后测试了一下这样的 strcpy
#define _strcpy(t,s) memcpy((t),(s),strlen(s)
代码如下
#include <stdio.h>
#include <string.h>
#define _strcpy(t,s) memcpy((t),(s),strlen(s))
int main()
{
char str[20] = "hello,world!\n";
_strcpy(str+6 , str);
printf("%s\n",str);
return 0;
} 倒是没有出现 strcpy(str + 6 , str) 崩溃的情况~~~~~而且目的也达到了,但是在测试的时候发现,gcc 和 vc6 在处理 memcpy 有覆盖的时候,居然动作不一样, gcc 就是那么从前往后复制,覆盖了就覆盖了(类似于strcpy),而 vc6 在存在覆盖时从后往前复制,保证数据按原样复制(另一个版本的memmove?)。 个人是比较喜欢 vc6 的方式,而gcc 也是对的,但是类似于 memcpy 这样的函数,主流编译器的结果居然不一样,还是让我觉得特别坑爹。另,附上云风blog 上关于vc6 的memcpy 的测试http://blog.codingnow.com/2005/10/vc_memcpy.html
另外,看雪上有一个专门的帖子讲过,地址忘了,不过说的也是 MS 的处理方式(覆盖时,倒序Copy);