阅读strcpy
函数的手册时,我发现还存在一个stpcpy
函数。然而,在手册中我注意到的唯一区别是:
char *
stpcpy(char *s1, const char *s2);
char *
strcpy(char *restrict s1, const char *restrict s2);
那么,这里的restrict
是什么意思?
阅读strcpy
函数的手册时,我发现还存在一个stpcpy
函数。然而,在手册中我注意到的唯一区别是:
char *
stpcpy(char *s1, const char *s2);
char *
strcpy(char *restrict s1, const char *restrict s2);
那么,这里的restrict
是什么意思?
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
不是。
strcat
没有任何有意义的用途。strcat
的独特糟糕设计使其成为 Joel on Software 博客文章中引入“Shlemiel the painter's algorithm”术语的典型例子。 - ShadowRangerrestrict
关键字告诉编译器,s1
和s2
指向不同的数组,并且指向的数组没有重叠。在某些情况下,这可能允许编译器执行额外的优化(例如,它可能可以复制多个字符块而无需检查重叠)。stpcpy
返回指向被复制到目标缓冲区中的\0
的指针,而strcpy
返回指向字符串开头的指针(实际上它执行了return s1;
)。stpcpy
是POSIX标准的一部分:http://pubs.opengroup.org/onlinepubs/9699919799/functions/stpcpy.html。 - R.. GitHub STOP HELPING ICErestrict
告诉编译器 s1 和 s2 指向的内存段不重叠;这使得代码可以执行更少的错误检查。< /p >< p >关于 restrict
的维基百科条目< /a >< /p >
stpcpy()
函数将src指向的字符串(包括终止的'\0'
字符)复制到dest指向的数组中。这两个字符串不能重叠,目标字符串dest必须足够大以接收复制内容。
即使在函数签名中没有使用restrict
,也满足其要求。如果有C99,则可以添加。
stpcpy()
函数返回指向字符串dest结尾(即终止空字节的地址)的指针,而不是开头。
这使您更轻松、更有效地连接多个字符串,因为可以将src
“附加”到上一个stpcpy()
返回的指针上。而替代方法strcat
的朴素实现必须在开始复制之前找到dest
字符串的结尾。
请注意以下内容:
此函数不属于C或POSIX.1标准,也不是Unix系统的惯例,但也不是GNU发明。也许它来自MS-DOS。现在,在BSD上也存在该函数。
stpcpy
不是 C(或 POSIX)的一部分有点困惑,因为我看到的 man 页面除了包含 string.h 之外没有其他要求。但是你提到的 BSD 让我明白了。我使用的是一个被广泛称为 Mac OS X 的 FreeBSD 版本。 - sidyllstrcpy函数返回s1,而stpcpy函数返回s1+strlen(s2)。