Connecting Tech Pros Worldwide Forums | Help | Site Map

Pointer to pointer

david
Guest
 
Posts: n/a
#1: Nov 21 '08
hi friends, don't understand this:

/*
**p is a pointer to *a[], but if *a stops increasing when reads abc,
where is pointing *p??
*/

#include <stdio.h>

int main(void)
{
char *a[] = {"abc", "def", "ghi", "jkl", NULL};
char **p;

p = (char **)a;
while (*p) {
while (**p) {
printf("*a=%p *p=%p %c %s\n", *a, *p, **p, *p);
(*p)++;
}
p++;
}

return 0;
}

/*
Returns
david@debian:~$ ./demo
*a=0x4005ec *p=0x4005ec a abc
*a=0x4005ed *p=0x4005ed b bc
*a=0x4005ee *p=0x4005ee c c
*a=0x4005ef *p=0x4005f0 d def -----Here *a stops inc, ¿where is
pointing *p?
*a=0x4005ef *p=0x4005f1 e ef
*a=0x4005ef *p=0x4005f2 f f
*a=0x4005ef *p=0x4005f4 g ghi
*a=0x4005ef *p=0x4005f5 h hi
*a=0x4005ef *p=0x4005f6 i i
*a=0x4005ef *p=0x4005f8 j jkl
*a=0x4005ef *p=0x4005f9 k kl
*a=0x4005ef *p=0x4005fa l l
*/


James Kuyper
Guest
 
Posts: n/a
#2: Nov 21 '08

re: Pointer to pointer


david wrote:
Quote:
hi friends, don't understand this:
>
/*
**p is a pointer to *a[], but if *a stops increasing when reads abc,
where is pointing *p??
*/
>
#include <stdio.h>
>
int main(void)
{
char *a[] = {"abc", "def", "ghi", "jkl", NULL};
char **p;
>
p = (char **)a;
In most contexts, an array name is automatically converted into a
pointer to the first element of the array, so the simple expression 'a'
already has the type "char**", there's no need for the cast. If a cast
were necessary, it would also indicate a design error.
Quote:
while (*p) {
while (**p) {
printf("*a=%p *p=%p %c %s\n", *a, *p, **p, *p);
The "%p" format specifier expects a void* argument. This is one of the
few places where a cast is routinely needed and perfectly correct:

printf("*a=%p *p=%p %c %s\n", (void*)*a, (void*)*p, **p, *p);
Quote:
(*p)++;
}
p++;
}
>
return 0;
}
>
/*
Returns
david@debian:~$ ./demo
*a=0x4005ec *p=0x4005ec a abc
*a=0x4005ed *p=0x4005ed b bc
*a=0x4005ee *p=0x4005ee c c
Up to this point, p == a, so *p == *a, or in other words, *p == a[0].
Then you execute p++. The result is that p == a+1, so *p == *(a+1), or
in other words *p == a[1].
Quote:
*a=0x4005ef *p=0x4005f0 d def -----Here *a stops inc, ¿where is
pointing *p?
Since p is now pointing at a[1], (*p)++ no longer changes the value of
*a. It is now changing the value of *(a+1).
Ben Bacarisse
Guest
 
Posts: n/a
#3: Nov 21 '08

re: Pointer to pointer


david <davranfor@gmail.comwrites:
Quote:
hi friends, don't understand this:
>
/*
**p is a pointer to *a[], but if *a stops increasing when reads abc,
where is pointing *p??
*/
>
#include <stdio.h>
>
int main(void)
{
char *a[] = {"abc", "def", "ghi", "jkl", NULL};
char **p;
>
p = (char **)a;
I'd drop the cast.
Quote:
while (*p) {
while (**p) {
printf("*a=%p *p=%p %c %s\n", *a, *p, **p, *p);
Technical matter: %p expects arguments of type void * and the
conversion is not done automatically so you need to write:

printf("*a=%p *p=%p %c %s\n", (void *)*a, (void *)*p, **p, *p);

Initially, *a and *p refer t the same object (a[0] -- the first
pointer in a). when you...
Quote:
(*p)++;
increment *p, you also change *a. But as soon as you...
Quote:
}
p++;
move p on to the next element (a[1]), *a will remain the same.
Quote:
}
>
return 0;
}
>
/*
Returns
david@debian:~$ ./demo
*a=0x4005ec *p=0x4005ec a abc
*a=0x4005ed *p=0x4005ed b bc
*a=0x4005ee *p=0x4005ee c c
*a=0x4005ef *p=0x4005f0 d def -----Here *a stops inc, ¿where is
pointing *p?
*a=0x4005ef *p=0x4005f1 e ef
*a=0x4005ef *p=0x4005f2 f f
*a=0x4005ef *p=0x4005f4 g ghi
*a=0x4005ef *p=0x4005f5 h hi
*a=0x4005ef *p=0x4005f6 i i
*a=0x4005ef *p=0x4005f8 j jkl
*a=0x4005ef *p=0x4005f9 k kl
*a=0x4005ef *p=0x4005fa l l
*/
--
Ben.
david
Guest
 
Posts: n/a
#4: Nov 21 '08

re: Pointer to pointer


Thanks James, and thanks for the corrections too!!!
david
Guest
 
Posts: n/a
#5: Nov 21 '08

re: Pointer to pointer


Thanks ben!!!
blargg
Guest
 
Posts: n/a
#6: Nov 21 '08

re: Pointer to pointer


david wrote:
Quote:
hi friends, don't understand this:
>
/*
**p is a pointer to *a[], but if *a stops increasing when reads abc,
where is pointing *p??
*/
>
#include <stdio.h>
>
int main(void)
{
char *a[] =3D {"abc", "def", "ghi", "jkl", NULL};
char **p;
>
p =3D (char **)a;
while (*p) {
while (**p) {
printf("*a=3D%p *p=3D%p %c %s\n", *a, *p, **p, *p);
(*p)++;
}
p++;
}
>
return 0;
}
>
/*
Returns
david@debian:~$ ./demo
*a=3D0x4005ec *p=3D0x4005ec a abc
*a=3D0x4005ed *p=3D0x4005ed b bc
*a=3D0x4005ee *p=3D0x4005ee c c
*a=3D0x4005ef *p=3D0x4005f0 d def -----Here *a stops inc, =BFwhere is
pointing *p?
[...]
Quote:
*/
Here's the state of p and the elements of a. You're incrementing the
actual pointers in the array, then once they reach the nul terminator,
moving to the next pointer in the array. (view in a monospace font, like
Courier)

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ec *p=3D0x4005ec a abc

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ed *p=3D0x4005ed b bc

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ee *p=3D0x4005ee c c

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f0 d def

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f1 e ef

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f2 f f

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f4 g ghi

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f5 h hi

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f6 i i

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f8 j jkl

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005f9 k kl

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^

*a=3D0x4005ef *p=3D0x4005fa l l

"abc\0" "def\0" "ghi\0" "jkl\0"
a[0]^ a[1]^ a[2]^ a[3]^ a[4]=NULL
p^
Closed Thread