a is an array of 3 pointers to const char.
p is a pointer to an array of 3 pointers to const char.
Yes the syntax for declaring a pointer to an array is a bit confusing because you have to put the asterisk and the variable name inside parentheses but it's necessary otherwise the compiler would think the asterisk was part of the element type.
1 2
int *x[5]; // an array of 5 pointers to int.
int (*y)[5]; // a pointer to an array of 5 ints.
constchar*(*p)[3] is a pointer to an array of 3 pointers to a constant char.
Or maybe a more intuitive way to say it: a pointer to an array of 3 constant C strings.
To read these kind of expressions you need to know some rules:
1. const applies to anything to its immediate left (or if there is nothing to the left, then to whatever is to its immediate right)
2. Start at the identifier name. First, look to your right. If there is a [n] read it as 'array n of'. Now look to your left. If there is a * read that as 'a pointer to'. If there are multiple [n][m] read it as 'array n of array m of'. If there are multiple ** read it as 'a pointer to a pointer to'. The arrays always have precedence over *.
3. Go up one level (in parentheses) and repeat the algorithm in 2.
Example:
1 2 3 4 5
p //p
*p //p is a pointer
(*p)[3] //p is a pointer to an array 3
*(*p)[3] //p is a pointer to an array 3 of pointers
constchar *(*p)[3] //p is a pointer to an array 3 of pointers to a const char
if a is an array of pointers to const char's what is the right hand side doing?
const char* a[3] = { "one", "two", "three" };
how can we the pointers in this way?
I thought a pointer holds a memory address but here we are passing the values in as strings?
I thought that before the declaration above call we would have created 3 const c style strings then assigned the char instead of doing this = { "one", "two", "three" };
If a is an array of pointers to const char's what is the right hand side doing?
The right hand side is giving you three constchar * pointers.
Each literal is a const char pointer to a C-string. The initialization list consists of three const char * pointers which matches the declaration of a[3] perfectly.
I thought a pointer holds a memory address
It does.
I thought that before the declaration above call we would have created 3 const c style strings
The result of creating the strings was the address of each of the C-style strings.
Well, to briefly return to the previous example. A C-string can be declared like this:
char a[4] = "one";
but it can also be declared like this:
constchar* a = "one";
In the first, we declare an array. The second, there is no array, just a pointer. The pointer is pointing to the C-string which the compiler has placed somewhere in read-only memory.
The array constchar* a[3] = { "one", "two", "three" }; contains three such pointers. The strings themselves are placed in some location determined by the compiler. We are not declaring storage for the actual strings. Just the pointers which point to those strings.
so basically in the second example a[3] is a pointer array to const chars and by doing using the initialisation block {} we are setting the values of what ever these pointers point to,to a c style string?
so for example a[0] = some memory address that holds the string "one"?