Reputation: 48956
Say we have the following array:
char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};
If we want to create a pointer that points to the array above, why should we use a two-level pointer as follows?
char **p1 = names;
Thanks.
Upvotes: 1
Views: 878
Reputation: 42149
Your names
is an array []
, of char *
, i.e., an array of pointers to char
.
Meanwhile p1
is a pointer which points to a pointer to char
, i.e., a pointer to char *
. You can assign names
to it because the array decays to a pointer to its first element, and the first element of names
is a pointer to char
, hence names
decays to a pointer to char *
. This is the same type – char **
– as p1
, therefore they are compatible.
(On another note, the element type of names
is incorrect; the string literals are constant, and thus it should be const char *names[]
, and similarly p1
should be const char**
– pointer to pointer to const char
.)
Upvotes: 5
Reputation: 8396
EDIT: Thanks to the comment, the array is actually bound here: because the compiler can deduce its size from the initializers.
From its declaration, names
is: an array of pointers to char
. A bound array decays to a pointer to its first element. Elements of names
being pointer to char, when used in an expression names
is implicitly converted to a pointer to a pointer to char.
This is why you can assign names
in your second line:
char **p1 = names;
So p1
points to the first element in names
, which for most practical purposes is like pointing to the array (in memory, an array being juxtaposed objects). Technically, you are pointing to the first element though.
Upvotes: -1
Reputation: 311088
If you want to create a pointer that points to array
char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};
then you have to write
char * ( *p1 )[sizeof( names ) / sizeof( *names )] = &names;
If you want to create a pointer that points to the elements of the array then you indeed should write
char **p1 = names;
In this case pointer p1
is initialized by the address of the address of the first character of string literal "Abc"
.
So for example expression *p1
will contain the value of the first element of array names
that in turn (the value) is the address of the first character of string literal "Abc"
and has type char *
.
If you will apply dereferencing the second time **p1
you will get the first character of the string literal itslef that is 'A'
.
For example
printf( "%c\n", **p1 );
To make it more clear let's consider a general situation.
If you have an array with elements of type T
like this
T a[N];
then this array in expressions is converted to pointer to its first element that will have type T *
. So if you want to declare such a pointer yourself you should write
T *p1 = a;
This record is equivalent to
T *p1 = &a[0];
In your original example type T
corresponds to type char *
- the type of the elements ofarray names. So after substitution char *
for T
you will get
char * *p1 = names;
^^^^^^
T
Upvotes: 1
Reputation: 16607
You did not create a pointer to array of pointers .It actually is pointer to first pointer of array.
If you want to create a pointer to array of pointers write something like this -
char *names[MAX];
char* (*p1)[MAX] = &names;
Upvotes: 1
Reputation: 12272
You can see it this way, when you need to point to an integer array, you need to use a pointer to int.
int arr[];
int* a;
a = arr;
So, in this context, you need a pointer to the elements in the array names[]
. What are the elements in that array. Its char*
. So you would need a pointer to char*
. Which translates to pointer to pointer to char.
That is
char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};
char **p1 = names;
Upvotes: 1