Because some functions in C support only C strings, I am trying to learn about them.
But I am really confused, what's the difference between the following:
char charr1[] = "Hello!";
char * charr2 = "Hello!";
So if the 1st is a char array, and the second is a char pointer, then what is a C String?
A C string is a char array where the last character of the actual string is followed by null ('\0').
Therefore, charr1 is a C string and charr2 points to a C string (or rather, to its first character) (although you need to fix the type, which must be const char*).
If it's const then I can't modify it's content, but apparently I do. What confuses me is that shouldn't we write:
1 2
char * charr2;
charr2 = newchar[6];
No, you're assigning the address of the first character in the string literal "Hello!" (which is stored somewhere, usually in a read-only memory region) to charr2. String literals are constant character arrays, so you shouldn't be able to assign its address to a non-const char pointer. If your compiler does not report an error, it is probably outdated.
ToniAz wrote:
And I didn't include a null character in either of charr1 or charr2. Does the null character get automatically inserted?
Yes. char charr1[] = "Hello!"; is equivalent to: char charr1[7] = {'H','e','l','l','o','!','\0'};
When declaring variables usage of empty [brackets] automatically sizes the array to the appropriate size. For example:
1 2 3 4 5
// this line:
int foo[] = {1,2,3};
// is the same as this line:
int foo[3] = {1,2,3};
With char arrays, the same idea applies:
1 2 3 4 5 6 7 8 9
char foo[] = "Hello!";
// is the same as:
char foo[7] = "Hello!";
// is the same as:
char foo[7] = {'H','e','l','l','o','!', 0};
// (note the null terminator is put there automatically by the "double quotes")
On the other hand... when you use char* you only have a pointer and not an array. The pointer points to characters that exist somewhere in memory.
If you make a pointer point to a string literal, then the pointer must be const, because you can't modify a string literal. It doesn't make sense to change the literal string "Hello!" to be something else, any more than it makes sense to change the literal number 5 to be a different number:
1 2 3 4 5 6
int* foo = &5; // conceptual only, not legal C++
*foo = 3; // this is like saying 5 = 3; ... which is nonsense.
// same idea applies to char arrays:
char* foo = "bar";
foo[0] = 'c'; // is like saying "bar" = "car" ... which makes no sense