While reading the man page for strcpy
, I discovered the function stpcpy
also exists. However, the only difference I could notice in the man page is:
char *
stpcpy(char *s1, const char *开发者_开发百科s2);
char *
strcpy(char *restrict s1, const char *restrict s2);
So, what does restrict
means here?
The question you are asking in the title and the question about restrict
are actually two different totally unrelated questions. The other answers have already provided you with some good links that will help you to learn more about restrict
.
However, the main difference between these two functons in not really the restrict
specifier. In fact, in C99 version of C language specification, strcpy
also has restrict
qualification on its parameters. What you see on your man page for strcpy
is simply not updated to conform to C99.
The main difference (which you seem to have missed) is the return value of stpcpy
. stpcpy
returns the pointer to the terminating \0
character of the target string. This immediately makes clear the purpose of stpcpy
and the rationale behind its existence: this function is intended to be used as an intelligent replacement to strcat
function in situations when you need to concatenate multiple sub-strings into one string. You see, strcat
works pretty poorly in such application (I'd even say that strcat
has no meaningful uses in real code). The problem with strcat
is that it rescans the destination string every time you add something to it, thus doing lots of unnecessary work and basically generating more heat than light. For example, the following code suffers from that problem
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);
This code can be reimplemented in a much more reasonable way by using stpcpy
stpcpy(stpcpy(stpcpy(stpcpy(buffer, part1), part2), part3), part4);
And if you don't like chained calls, you can use an intermediate pointer to store the return value of intermediate stpcpy
calls
char *end = buffer;
end = stpcpy(end, part1);
end = stpcpy(end, part2);
end = stpcpy(end, part3);
end = stpcpy(end, part4);
Of course it is worth mentioning that strcpy
and strcat
are standard functions, while stpcpy
is not.
The restrict
tells the compiler that s1
and s2
point to different arrays and that there is no overlap in the pointed-to arrays. In some cases this may allow the compiler to perform extra optimizations (i.e., it could possibly copy blocks of multiple characters without having to check for overlap).
Note also that the return value is different: stpcpy
returns a pointer to the \0
that was copied into the destination buffer while strcpy
returns a pointer to the beginning of the string (effectively it does a return s1;
).
Wikipedia entry for restrict
In short, restrict
tells the compiler that the segments of memory pointed to by s1 and s2 do not overlap; this allows the code to perform less error checking.
The
stpcpy()
function copies the string pointed to by src (including the terminating'\0'
character) to the array pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.
This satisfies the requirements for restrict
, even if it's not in the function signature. If C99 is present, it could be added.
stpcpy()
returns a pointer to the end of the string dest (that is, the address of the terminating null byte) rather than the beginning.
This enables you to concatenate many strings more easily, and more efficiently, as src
can be "tacked" onto the pointer returned from the last stpcpy()
. The naive implementation of the alternative, strcat
has to locate the end of the dest
string before it can commence copying.
Note the following:
This function is not part of the C or POSIX.1 standards, and is not customary on Unix systems, but is not a GNU invention either. Perhaps it comes from MS-DOS. Nowadays, it is also present on the BSDs.
The other difference is the return value. From the man page: "The strcpy() and strncpy() functions return s1. The stpcpy() function returns a pointer to the terminating `\0' character of s1."
strcpy returns s1 but stpcpy returns s1+strlen(s2).
精彩评论