在阅读strcpy
的手册页时,我发现函数stpcpy
也存在。但是,我在手册页中注意到的唯一区别是:
char *
stpcpy(char *s1, const char *s2);
char *
strcpy(char *restrict s1, const char *restrict s2);
那么,restrict
在这里意味着什么?
答案 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);
当然值得一提的是strcpy
和strcat
是标准函数,而stpcpy
则不是。
答案 1 :(得分:17)
restrict
告诉编译器s1
和s2
指向不同的数组,并且指向数组中没有重叠。在某些情况下,这可能允许编译器执行额外的优化(即,它可能复制多个字符的块而不必检查重叠)。
另请注意,返回值不同:stpcpy
返回指向已复制到目标缓冲区的\0
的指针,而strcpy
返回指向字符串开头的指针(实际上它有return s1;
)。
答案 2 :(得分:6)
简而言之,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)。