char * a[] = {"red shoes"}; // array of 1 character pointer pointing to base address of string constant.
( only 1 but it can be extended like {"red shoes", "blue tie"}; now we have array of 2 pointers. 1st pointer is pointing to continuous locations containing 9 character and 2nd pointer is pointing to another continuous locations containing 8 characters.
Content will be addresses. Here, only 1 address in case of "red shoes".
a[0] = base address of 1st pointer. ie. 1000 (this pointer points to our characters ie. within 9 blocks)
a[1] = base address of 2nd pointer. ie 1010 because of gap of 9 + 1 null character.
a[2] = base address of 3rd pointer. lets say 1025 and so on..... thus this pointers locations are non-continuous locations. See 1000, 1010, 1025.....
our 1st pointer will point to all the characters at continuous memory locations.
ie. a[0] = contains base address of 1st string constant = 1000
a[0][0] = r and &(a[0][0]) =1000
a[0][1] = e and &(a[0][1]) =1001 (yes address of a[1] != 1000)
a[0][2] = d and &(a[0][2]) =1002
a[0][3] = ' ' and &(a[0][3]) =1003
a[0][4] = s and &(a[0][4]) =1004
a[0][5] = h and &(a[0][5]) =1005
a[0][6] = o and &(a[0][6]) =1006
a[0][7] = e and &(a[0][7]) =1007
a[0][8] = s and &(a[0][8]) =1008
a[0][8] = ' \0 ' and &(a[0][9]) =1009 its the ending of string constant so NULL
I used this program to understand it..
copy paste it in devcpp and run it for yourself to understand better.
#include<iostream>
using namespace std;
int main()
{
char* a[] = {"red shoes","blue tie"};
printf("%u %u %u %u %u %c %c ", a[0], a[1], &(a[0]), &(a[0][0]), &(a[0][1]), a[0][0], a[0][8]);
//printf("%u %c %u %u %c %c %c %c",a[0], *(a[0]+1), &(a[0][0]), &(a[0][1]), a[0][0], a[0][1], a[1][0], a[1][1]);
}