So in general if you create a string like that
Code:
char string[9];
string[1] = 'E';
This is just normal array of chars, it's fine to modify in whatever way you like (with a caveat that if you treat it as a null-terminated string - you have to have a null character ('\0') at the end of your string (notice, that's not necessarily end of your array!). That's because standard string functions will assume that your string is, well, null-terminated.
Code:
char string[] = "Hello";
string[1] = 'E';
That works too. Here you define an array of chars that will be properly sized based on the string literal. So string will be char[6], and contents of read-only string literal "Hello" will be copied over to it.
Code:
char string[6] = "Hello";
string[1] = 'E';
That works as well. Here you define an array of chars with length of 6 and the contents of read-only string literal "Hello" will be copied over to it. Notice, though, that if you'd make it char[5] - the terminating character won't be copied over, and you will have to add it yourself. It's safer to omit array size here, make the compiler count the characters for you.
So i assume that if you create a char pointer then the string is automatically declared as constant?
No, it has nothing to do with pointers - rather with the thing you're pointing to - the string literal.
Code:
char* string = "Hello";
string[1] = 'E';
If that works - then it's by sheer luck, or blessing of the Chaos Gods. What you have here is string is a pointer to char, and you assign to it the address of a read-only string literal. In itself, that's fine, because C - even in It'll probably compile fine, but during runtime it may do whatever Chaos Gods wish it. I get a segmentation fault. Phew, lucky.
Standardese about string literals:
[6.4.5 String literals N1570, C11]
7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values.
If the program attempts to modify such an array, the behavior is undefined.
[...]
32 On the other hand, the declarationdefines p with type ‘‘pointer to char’’ and initializes it to point to an object with type ‘‘array of char’’ with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array, the behavior is undefined.[/quote]
You can still safely use pointers to string literals though, and make your compiler scream at you if you attempt to modify a string literal through such a pointer - just make 'em const:
Code:
const char* p = "hello world!";
p[1] = 'E'; // error: assignment of read-only location
Here's an example of using a pointer:
Code:
char* p = malloc(10); //dynamically allocated memory strcpy(p, "yolo!");
puts(p);
free(p);
char foo[] = "Hello!";
char* bar = foo;
bar[1] = 'E';
puts(foo);
puts(bar);
const char* fubar = foo;
fubar[1] = 'e'; //kaboom!