Let's look into it (for the following, note char const
and const char
are the same in C++):
String literals and char *
"hello"
is an array of 6 const characters: char const[6]
. As every array, it can convert implicitly to a pointer to its first element: char const * s = "hello";
For compatibility with C code, C++ allows one other conversion, which would be otherwise ill-formed: char * s = "hello";
it removes the const!. This is an exception, to allow that C-ish code to compile, but it is deprecated to make a char *
point to a string literal. So what do we have for char * s = "foo";
?
"foo"
-> array-to-pointer
-> char const*
-> qualification-conversion
-> char *
. A string literal is read-only, and won't be allocated on the stack. You can freely make a pointer point to them, and return that one from a function, without crashing :).
Initialization of an array using a String literal
Now, what is char s[] = "hello";
? It's a whole other thing. That will create an array of characters, and fill it with the String "hello"
. The literal isn't pointed to. Instead it is copied to the character-array. And the array is created on the stack. You cannot validly return a pointer to it from a function.
Array Parameter types.
How can you make your function accept an array as parameter? You just declare your parameter to be an array:
void accept_array(char foo[]);
but you omit the size. Actually, any size would do it, as it is just ignored: The Standard says that parameters declared in that way will be transformed to be the same as
void accept_array(char * foo);
Excursion: Multi Dimensional Arrays
Substitute char
by any type, including arrays itself:
void accept_array(char foo[][10]);
accepts a two-dimensional array, whose last dimension has size 10. The first element of a multi-dimensional array is its first sub-array of the next dimension! Now, let's transform it. It will be a pointer to its first element again. So, actually it will accept a pointer to an array of 10 chars: (remove the []
in head, and then just make a pointer to the type you see in your head then):
void accept_array(char (*foo)[10]);
As arrays implicitly convert to a pointer to their first element, you can just pass an two-dimensional array in it (whose last dimension size is 10), and it will work. Indeed, that's the case for any n-dimensional array, including the special-case of n = 1
;
Conclusion
void upperCaseString(char *_str) {};
and
void upperCaseString(char _str[]) {};
are the same, as the first is just a pointer to char. But note if you want to pass a String-literal to that (say it doesn't change its argument), then you should change the parameter to char const* _str
so you don't do deprecated things.