I have three variables initialised below :
char c1[] = "Hello";
char c2[] = { 'H', 'e', 'l', 'l', 'o', '\0'};
char* c3 = "Hello";
I am aware that c1 and c2 are the same, and that they are both strings because they are terminated by \0. However, c3 is different from c1 and c2. Is this because c3 does not terminate with a \0? Does that mean that c3 is not a string? If c3 is not a string, then why does printf("%s", c3); not give an error? Thanks!
EDIT:
Is there a reason why c1 and c2 can be modified but c3 can’t?
In terms of C, the most pertinent difference between
c3and the others is that you are not allowed to attempt to modify the underlying characters withc3. I often find it helpful to think of it like this:will create a modifiable pointer on the stack and make it point at the non-modifiable character sequence
{'x','y','z','\0'}. On the other hand,will create a modifiable array on the stack big enough to hold the character sequence
{'x','y','z','\0'}and then copy that character sequence into it. The array contents will then be modifiable. Keep in mind the standard says nothing about stacks but this is commonly how it’s done. It is just a memory aid, after all.Formally,
c3is a pointer to a string literal whilec1andc2are both arrays of characters which both happen to end with a null character. When they’re passed to functions likeprintf, they decay to a pointer to the first element of the array which means they’ll be treated identically toc3within that function (actually they decay under quite a few circumstances, see third quote from c99 below for exceptions).The relevant sections of C99 are
6.4.5 String literalswhich explains why you’re not allowed to modify whatc3points to:and why it does have a null terminator:
And
6.3.2.1 Lvalues, arrays, and function designatorsunder6.3 Conversionsstates: