Reputation: 655
If this code is correct:
char v1[ ] = "AB";
char v2[ ] = {"AB"};
char v3[ ] = {'A', 'B'};
char v4[2] = "AB";
char v5[2] = {"AB"};
char v6[2] = {'A', 'B'};
char *str1 = "AB";
char *str2 = {"AB"};
Then why this other one is not?
char *str3 = {'A', 'B'};
To the best of my knowledge (please correct me if I'm wrong at any point) "AB" is a string literal and 'A' and 'B' are characters (integers,scalars). In char *str1 = "AB"; the string literal "AB" is defined and the char pointer is set to point to that string literal (to the first element). With char *str3 = {'A', 'B'}; two characters are defined and stored in subsequent memory positions, and the char pointer "should" be set to point to the first one. Why is that not correct?
In a similar way, a regular char array like v3[] or v6[2] can indeed be initialized with {'A', 'B'}. The two characters are defined, the array is set to point to them and thus, being "turned into" or treated like a string literal. Why a char pointer like char *str3 does not behave in the same way?
Just for the record, gcc compiler warnings I get are "initialization makes pointer from integer without a cast" when it gets to the 'A', and "excess elements in scalar initializer" when it gets to the 'B'.
Thanks in advance.
Upvotes: 0
Views: 2447
Reputation: 409136
There is one thing you need to learn about constant string literals. Except when used to initialize an array (for example in the case of v1
in your example code) constant string literals are themselves arrays. For example if you use the literal "AB"
it is stored somewhere by the compiler as an array of three characters: 'A'
, 'B'
and the terminator '\0'
.
When you initialize a pointer to point to a literal string, as in the case of str1
and str2
, then you are making those pointers point to the first character in those arrays. You don't actually create an array named str1
(for example) you just make it point somewhere.
The definition
char *str1 = "AB";
is equivalent to
char *str1;
str1 = "AB";
Or rather
char unnamed_array_created_by_compiler[] = "AB";
char *str1 = unnamed_array_created_by_compiler;
There are also other problematic things with the definitions you show. First of all the arrays v3
, v4
, v5
and v6
. You tell the compiler they will be arrays of two char
elements. That means you can not use them as strings in C, since strings needs the special terminator character '\0'
.
In fact if you check the sizes of v1
and v2
you will see that they are indeed three bytes large, once for each of the characters plus the terminator.
Another important thing you miss is that while constant string literals are arrays of char
, you miss the constant part. String literals are really read-only, even if not stored as such. That's why you should never create a pointer to char
(like str1
and str2
) to point to them, you should create pointers to constant char
. I.e.
const char *str1 = "AB";
Upvotes: 3
Reputation: 1
(" ") is for string and (' ') is for character. for an string a memory has been allocated and for character not. pointers points to a memory and you must allocate an specified memory to it but for array of characters is not necessary.
Upvotes: 0