Why can I use pointers as strings when declared with double quotes, but not curly braces, in C?
In this case, pCow
is set to the address of a c-string in static memory:
char *pCow = "pCow goes MOO";
In this case, pCow
is set to the value 'p'
(i.e., 112
):
char *pCow = {'p','C','o','w',' ','g','o','e','s',' ','M','O','O','\0'};
Since the address 112
most likely points into restricted/invalid memory, that causes your program to blow up when you try to access pCow[counter]
.
The warning "excess elements in scalar initializer" is telling you that it's ignoring all of the stuff after the 'p'
since the pointer only needs one value.
The warning "initialization makes pointer from integer without a cast" is telling you that you're using 'p'
as a pointer, which probably isn't a good idea...
What you want to do is declare pCow
as a character array rather than a character pointer if you want to use the initializer syntax:
char pCow[] = {'p','C','o','w',' ','g','o','e','s',' ','M','O','O','\0'};
"pCow goes MOO"
is a string literal and have two different uses. Either you can use it as an initializer to an array:
char aCow[] = "pCow goes MOO";
In which case the contents of the string literal are copied into the array.
Or alternatively, you can use a string literal as a stand-alone constant array anywhere in your program. For example strcpy(cow, "pCow goes MOO");
. So there's a distinctive difference between these two:
char aCow[] = "pCow goes MOO";
char* pCow = "pCow goes MOO";
In the first case, the literal is copied into the array. In the second case, the literal remains a stand-alone constant in read-only memory, which we point to with a pointer. The former can be modified, the latter cannot.
As for the case of
char *pCow = {'p','C','o','w',' ','g','o','e','s',' ','M','O','O','\0'};
You are using a pointer, but you have no string literal. Instead you have an initializer list intended for an array. A good compiler would warn you for "excess initializer". The reason that the code compiles is a very odd rule in C which is allowing plain variables to be initialized with braces, for example int x = {1};
. So the compiler uses this rule to initialize your pointer to point at the address 'p'
, which is of course nonsense, and then it discards the rest of the initializer list.