strcpy和stpcpy有什么区别?

时间:2011-04-29 01:01:40

标签: c string

在阅读strcpy的手册页时,我发现函数stpcpy也存在。但是,我在手册页中注意到的唯一区别是:

char *
stpcpy(char *s1, const char *s2);

char *
strcpy(char *restrict s1, const char *restrict s2);

那么,restrict在这里意味着什么?

6 个答案:

答案 0 :(得分:24)

您在标题中提出的问题以及有关restrict的问题实际上是两个完全不相关的问题。其他答案已经为您提供了一些很好的链接,可以帮助您了解有关restrict的更多信息。

然而,这两个功能的主要区别并不在于restrict说明符。事实上,在C语言规范的C99中,strcpy对其参数也有restrict条件。您在strcpy的手册页上看到的内容根本未更新为符合C99。

主要区别(您似乎错过了)是stpcpy的返回值。 stpcpy返回指向目标字符串的终止\0字符的指针。这立即明确了stpcpy的目的及其存在的基本原理:当你需要将多个子串连接成一个子串时,这个函数用作strcat函数的智能替代。串。你看,strcat在这样的应用程序中效果很差(我甚至说strcat在实际代码中没有任何有意义的用途)。 strcat的问题在于,每次向其添加内容时它都会重新扫描目标字符串,因此会进行大量不必要的工作,并且基本上会产生比光更多的热量。例如,以下代码遇到了该问题

const char *part1, *part2, *part3, *part4;
...
char buffer[size]; /* assume that `size` is calculated properly */

strcpy(buffer, part1);
strcat(buffer, part2);
strcat(buffer, part3);
strcat(buffer, part4);

使用stpcpy

可以更合理地重新实现此代码
stpcpy(stpcpy(stpcpy(stpcpy(buffer, part1), part2), part3), part4);

如果您不喜欢链式调用,可以使用中间指针存储中间stpcpy调用的返回值

char *end = buffer;

end = stpcpy(end, part1);
end = stpcpy(end, part2);
end = stpcpy(end, part3);
end = stpcpy(end, part4);

当然值得一提的是strcpystrcat是标准函数,而stpcpy则不是。

答案 1 :(得分:17)

restrict告诉编译器s1s2指向不同的数组,并且指向数组中没有重叠。在某些情况下,这可能允许编译器执行额外的优化(即,它可能复制多个字符的块而不必检查重叠)。

另请注意,返回值不同:stpcpy返回指向已复制到目标缓冲区的\0的指针,而strcpy返回指向字符串开头的指针(实际上它有return s1;)。

答案 2 :(得分:6)

Wikipedia entry for restrict

简而言之,restrict告诉编译器s1和s2指向的内存段不重叠;这允许代码执行较少的错误检查。

答案 3 :(得分:4)

  

stpcpy()函数将src指向的字符串(包括终止'\0'字符)复制到dest指向的数组。字符串          可能不重叠,目标字符串dest必须足够大才能接收副本。

这满足restrict的要求,即使它不在函数签名中。如果存在C99,则可以添加。

  

stpcpy()返回指向字符串dest末尾的指针(即终止空字节的地址)而不是开头。

这使您可以更轻松,更有效地连接多个字符串,因为src可以“粘贴”到从上一个stpcpy()返回的指针上。替代方法strcat的天真实现必须在dest字符串开始复制之前找到它的末尾。

请注意以下事项:

  

此功能不是C或POSIX.1标准的一部分,在Unix系统上不是惯用的,但也不是GNU的发明。也许吧          来自MS-DOS。如今,它也出现在BSD上。

答案 4 :(得分:3)

另一个区别是返回值。从手册页:“strcpy()和strncpy()函数返回s1.stpcpy()函数返回指向s1的终止”\ 0“字符的指针。”

答案 5 :(得分:3)

strcpy返回s1但是stpcpy返回s1 + strlen(s2)。