Let's get pedantic here.
char const * const p_foo = "foo";
The above defines a {constant} pointer to the {constant} character literal "foo". The pointer is to the single first character of the character literal.
const char bar[] = "bar";
- The above defines a character array.
- The character array is *read-only".
- The character array is the length of the text literal "bar" plus a
nul terminator (4 characters).
- The contents of the text literal are copied into the array. (The
compiler may optimize this step away).
Fundamentally, you have the difference between a pointer to the first character of a literal and an array.
The pointer is pointing to a single character. Incrementing the pointer may not point to a valid entity (since it is not an array, but a pointer to a single datum). There is an underlying assumption that the pointer can be incremented to the next character.
With an array you know that there are more than one character sequentially in memory (provided the array is of length 2 or more). You don't know if there is a terminating nul in the sequence (collection). You can assume that, but an array of characters does not guarantee that.
Usages
With the array declaration, the length of the text is known at compile time.
With the pointer declaration, you would need to use strlen
to determine the length of the text at run-time. The run-time code doesn't know the length of the target data string; only a length of 1 can be guaranteed.
Sometimes, using static
and const
can help the compiler optimize.
For example:
static const char moo[] = "moo";
allows the compiler to access the text directly without creating an array variable and copying the text into the variable.
In a function that receives a pointer to a character, you can't guarantee that the pointer points to a valid location (the content of the pointer can be invalid).
Each declaration has its benefits and side-effects.
The choice is yours.