Talking about strings in C++, what is the difference between the following st开发者_StackOverflow社区atements: s1=s2
and strcpy (s1, s2)
? Supposing that s1
and s2
are (original version: type ', as revised) type char
'char *
.
Given:
char s1, s2;
...
s1 = s2; // Assigns value in s2 to s1
strcpy(s1, s2); // Error detected by compiler; strcpy() takes char pointers
Given:
char *s1, *s2;
...
s1 = s2; // s1 points to the same 'string' that s2 does
strcpy(s1, s2); // the space pointed to by s1 contains the same
// characters as the space pointed to by s2.
In the second case (pointers), there are a number of caveats about making sure you have enough space allocated for the actual string - as opposed to the pointers. The triple dots indicate where there is some work to be done to ensure things are initialized.
Difference between char
and char*
and char* null terminated string
:
At first your question asked about strcpy
and char
. char
holds a single character. Each char
has an address. The address of a char
is char*
It is very common in C/C++ to use a char*
to point to the first character of a null terminated character array. We consider a null terminated character array a null terminated string.
To know when the string contained inside the array ends, a null terminated character is added to the end of the string.
Null terminated strings:
const char *p = "hello";
const char *s = "world";
p = s;
Both p
and s
hold a memory address to the first element in the array of the string literal. When you say p = s you are simply changing what the p
variable holds to be the s
memory address value that s
holds.
So above originally p
may hold 0x94749248
, and s
may hold 0x84811409. And after the assignment p = s
, p
and s
hold 0x84811409
.
The actual array of characters are stored at memory address 0x84811409
strcpy:
strcpy works on char*
not char
. By char*
I mean a pointer to the first element of an array of chars, representing a null terminated string.
The following actually copies the data into szBuffer.
char szBuffer[512];
char *p = "hello world!";
strcpy(szBuffer, p);
Nowp
holds a memory address of the string literal "hello world!"
and szBuffer
holds its own copy of all of the characters.
szBuffer
after the call to strcpy
still holds the same 512 memory addresses. It's just that they have been filled with the values starting at *p
.
STL strings:
strings in C++ usually refer to STL strings.
#include <string>
std::string s = "hi";
There are several things wrong with your question, I'll try and clarify.
If S1 and S2 are of type char, then they're not strings, they're single characters, not strings of characters.
For S1 & S2 to be strings, they'd need to be declared like, char* s1 = ; char* s2 = ;
char* S1; says that S1 is not a character, but instead will point to a location in memory, and it will interpret what ever is stored there as a character. In classic C strings are represented as a sequence of characters in memory (stored contiguously, one beside the other). The end of the string is marked by the last character, which must be Zero (hence C strings are also called Zero Terminated Strings).
This idiom for defining strings can also be done in C++, but C++ has a specific string type declared in the Standard Template Library.
So, for the second part of your question, whats the difference between strcpy(S1, S2), and S1 = S2.
Firstly, for this question to make sense S1 and S2 must be character points (as shown in the first point). The difference is strcpy copies the string from one memory location to another (it literally moves through each character and copies it to the other memory location) while "S1 = S2", simply gets S1 to point to the same memory location that S2 points to e.g. Sample strcpy function, NB this code may not compile
function strcpy(char *destination, char* source)
{
while(*source != 0)
{
*destination = *source; /* assign this character to destination */
destination++; /* move the destination pointer to the next location*/
source++; /* move the source pointer to the next location */
}
*destination = 0; /* put a zero terminator into destination at the end of the string */
}
}
"S1 = S2" is dangerous because if you then add some characters to the string at S2, you will see those changes in S1, because they are both pointing at the same string.
NB strcpy expects there to be enough memory allocated at S1 to hold the contents of S2 PLUS an extra character for the Zero Terminator.
Hope this helps, if you need clarification on anything, just post a comment.
if s1 and s2 are of type char*, then
char* s1 = "Hello";
char* s2 = "World";
s1 = s2; // now s1 points to World.
now, if char s1[] = "Hello";
char s2[] = "World";
then, strcpy(s1, s2); // now s1 contains Hello .
char* s1 = "Hello";
char* s2 = "World";
then, strcpy(s1, s2); // this is undefined behaviour.
I assume you mean "s1
and s2
are type char*
", since the arguments to strcpy
are type char*
. This is an important distinction, because it means that s1
and s2
are pointers. (That's how strings are represented in C, pointers to a series of characters)
s1 = s2
assigns s1
to point to the same location as s2
. Since they both now refer to the same location, they are exactly the same string, and any change made to the string from one pointer appears when using the other pointer as well.
strcpy(s1, s2)
assumes that s1
already points to a memory block at least as large as the string pointed to by s2
. It copies the contents of the memory block pointed to by s2
into the memory block pointed to by s1
. Afterwords, the strings s1
and s2
have the same contents, but are still two different strings in two different locations and can be modified independently.
The difference is that s1 = s2
copies pointers (to contents) and strcpy(s1, s2)
copies the contents.
Let's look at the following code:
char* s1 = (char*)malloc(12*sizeof(char));
strcpy(s1, "Hello World");
s1
now points to the memory address, let's say 0x0123 with the contents of "Hello World".
char* s2;
s2 = s1;
Now s2
points to the same memory location that s1
, that is 0x0123.
char* s3 = (char*)malloc(12*sizeof(char));
strcpy(s3, s1);
In this case s3
points to a distinct memory address, let's say 0x0540 and has a copy of the contents of s1
, that being "Hello World".
Contents wise s1
, s2
and s3
look the same. The interesting thing happens when you do the following:
free(s1);
free(s2);
free(s3);
The first call to free
is valid, since the memory was properly allocated and all. The second call to free
is invalid (and will probably crash you app), since the memory at 0x0123 was already freed. The third call to free
is valid since the memory at 0x0540 is was not freed yet.
As you can see it depends on the distinct use. Copying the pointer is much faster than copying the contents but it needs clear definition of who is in change of the memory and a proper definition of the lifetime of the memory.
Since this question is tagged with c++, I will give the additional advice:
By default use std::string
. It removes many pitfalls when using strings. Yes, it is slower but 95% of the time you will never notice and in those cases where you do, you can think of a better way to do things.
I simply want to expand on Jonathan Leffler's answer slightly.
When you do s1 = s2
, the following is true:
s1[0] = 'h';
s2[0] = 'q';
s1[0] == 'q';
s2[0] == 'q';
When you use strcpy, the following is true:
s1[0] = 'h';
s2[0] = 'q';
s1[0] == 'h';
s2[0] == 'q';
精彩评论