469,926 Members | 1,514 Online

array of char pointers

And I thought I understood it, finally. Alas.
given:
char *s[]={"Jan","Feb","Mar","April"};

is it possible to have char *p point at s?

*p = s...does not do it, as I expect.
*p=s...I believe sets it to point to the first element in s. But
this is not what I want. What I want is a pointer which, when
incremented will produce "Jan","Feb","Mar","April" etc.

I believe what I want is a pointer equivalent of:

printf("%s", s[i]), (where i = 0->3)
Thanks.

Apr 18 '07 #1
14 70800 mdh wrote:
And I thought I understood it, finally. Alas.
given:
char *s[]={"Jan","Feb","Mar","April"};

is it possible to have char *p point at s?
It might be conceptually easier to think of s as a char**.

so given char* p;

p = s;

p now points to the string literal "Jan".
*p = s...does not do it, as I expect.
*p=s...I believe sets it to point to the first element in s. But
this is not what I want. What I want is a pointer which, when
incremented will produce "Jan","Feb","Mar","April" etc.
Then you want p to be another char**.
I believe what I want is a pointer equivalent of:

printf("%s", s[i]), (where i = 0->3)
char** p = s;

for( unsigned n = 0; n < 4; ++n )
{
printf("%s", *p );
++p;
}

--
Ian Collins.
Apr 18 '07 #2
On Apr 17, 6:59 pm, Ian Collins <ian-n...@hotmail.comwrote:
mdh wrote:
given:
char *s[]={"Jan","Feb","Mar","April"};
>
It might be conceptually easier to think of s as a char**.
Then you want p to be another char**.
char** p = s;

for( unsigned n = 0; n < 4; ++n )
{
printf("%s", *p );
++p;
Ian...got "JanJanJan"

if I replaced *p with *p++ got as expected.
Does this make sense?

Apr 18 '07 #3
mdh <m...@comcast.netwrote:
And I thought I understood it, finally. Alas.

given:
char *s[]={"Jan","Feb","Mar","April"};

is it possible to have char *p point at s?
No.
*p = s...does not do it, as I expect.
*p=s...I believe sets it to point to the first element in s. But
this is not what I want. What I want is a pointer which, when
incremented will produce "Jan","Feb","Mar","April" etc.
To point to an element, you need a pointer to the element type.

To point to an element of an array of elements, you need a
pointer to the element type.

So, to point to an element of an array of X, you need a pointer
to X.

Thus, to point to an element of an array of char *, you need
a pointer to char *. In other words, you need a char **.
I believe what I want is a pointer equivalent of:

printf("%s", s[i]), (where i = 0->3)
#include <stdio.h>

#define countof(X) ( (size_t) ( sizeof(X)/sizeof*(X) ) )

int main(void)
{
const char *s[]={"Jan","Feb","Mar","April"};
const char **p;
size_t i;

puts("Loop 1:");
for (i = 0; i < countof(s); i++)
puts(s[i]);

puts("\nLoop 2:");
for (p = s, i = 0; i < countof(s); i++)
puts(p[i]);

puts("\nLoop 3:");
for (p = s; p < &s[countof(s)]; p++)
puts(*p);

return 0;
}

Apr 18 '07 #4
mdh wrote:
>
>>It might be conceptually easier to think of s as a char**.
Then you want p to be another char**.
>char** p = s;

for( unsigned n = 0; n < 4; ++n )
{
printf("%s", *p );
++p;

Ian...got "JanJanJan"

if I replaced *p with *p++ got as expected.
Does this make sense?
I didn't test what I posted, but I just tried this and it worked as
expected. There shouldn't be any difference.

#include <stdio.h>

int main(void)
{
char *s[]={"Jan","Feb","Mar","April"};

char** p = s;

for( unsigned n = 0; n < 4; ++n )
{
printf("%s\n", *p );
++p;
}
}

--
Ian Collins.
Apr 18 '07 #5
On Apr 17, 7:11 pm, Peter Nilsson <a...@acay.com.auwrote:
mdh <m...@comcast.netwrote:
given:
char *s[]={"Jan","Feb","Mar","April"};
is it possible to have char *p point at s?

No.
ok.....

To point to an element, you need a pointer to the element type.

To point to an element of an array of elements, you need a
pointer to the element type.

So, to point to an element of an array of X, you need a pointer
to X.

Thus, to point to an element of an array of char *, you need
a pointer to char *. In other words, you need a char **.

Thank you Ian...that's a nice explanation.
>
#include <stdio.h>

#define countof(X) ( (size_t) ( sizeof(X)/sizeof*(X) ) )

int main(void)
{
const char *s[]={"Jan","Feb","Mar","April"};
const char **p;
size_t i;

puts("Loop 1:");
for (i = 0; i < countof(s); i++)
puts(s[i]);

puts("\nLoop 2:");
for (p = s, i = 0; i < countof(s); i++)
puts(p[i]);

puts("\nLoop 3:");
for (p = s; p < &s[countof(s)]; p++)
puts(*p);

return 0;
}

Thank you....and thank you for the code..I will follow along in the
debugger.

Michael.

Apr 18 '07 #6
On Apr 17, 7:11 pm, Peter Nilsson <a...@acay.com.auwrote:

Thus, to point to an element of an array of char *, you need
a pointer to char *. In other words, you need a char **.

Is this thus the equivalent of *argv[] which we see in main?
Apr 18 '07 #7
mdh said:
On Apr 17, 7:11 pm, Peter Nilsson <a...@acay.com.auwrote:

>Thus, to point to an element of an array of char *, you need
a pointer to char *. In other words, you need a char **.

Is this thus the equivalent of *argv[] which we see in main?

No. The only place that there is an exact equivalence between T ** and T
*[] is in a formal parameter declaration, and that's only for
hysterical reasons.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 18 '07 #8
mdh said:
Is this thus the equivalent of *argv[] which we see in main?
Richard Heathfield <r...@see.sig.invalidwrote:
No. The only place that there is an exact equivalence between T ** and T
*[] is in a formal parameter declaration, and that's only for
hysterical reasons.
Thanks.

Apr 18 '07 #9
mdh wrote:
On Apr 17, 6:59 pm, Ian Collins <ian-n...@hotmail.comwrote:
mdh wrote:
given:
char *s[]={"Jan","Feb","Mar","April"};

It might be conceptually easier to think of s as a char**.
Then you want p to be another char**.
char** p = s;

for( unsigned n = 0; n < 4; ++n )
{
printf("%s", *p );
++p;

Ian...got "JanJanJan"

if I replaced *p with *p++ got as expected.
Does this make sense?
Cut and paste the exact (complete minimal) program you ran. It should
not have done that. A good bet would be you forgot the braces, so you
ended up with:

for( unsigned n = 0; n < 4; ++n )
printf("%s", *p );
++p;

Brian

Apr 18 '07 #10
mdh wrote:
And I thought I understood it, finally. Alas.
given:
char *s[]={"Jan","Feb","Mar","April"};

is it possible to have char *p point at s?

*p = s...does not do it, as I expect.
*p=s...I believe sets it to point to the first element in s. But
this is not what I want. What I want is a pointer which, when
incremented will produce "Jan","Feb","Mar","April" etc.

I believe what I want is a pointer equivalent of:

printf("%s", s[i]), (where i = 0->3)
#include <stdio.h>
#include <string.h>

int main(void)
{
char *s[] = { "Jan", "Feb", "Mar", "April" };
char *p, **q, *endp;
size_t ns = sizeof s / sizeof *s, i;

printf("[Output for one implementation:\n\n");

printf("The original array has these contents\n");
for (i = 0; i < ns; i++)
printf("s[%zu] @ %p: \"%s\"\n", i, (void *) s[i], s[i]);
putchar('\n');

printf("p is a pointer to char, so incrementing it leads\n"
"to changes of 1 byte. For example, with\n"
"initialization of p=s, we can get:\n");
for (p = s, endp = strchr(s, 0); p <= endp; p++)
printf("@ %p: %o %c\n", (void *) p, *p, *p ? *p : ' ');
putchar('\n');

printf("q is a pointer to pointer to char, so incrementing it\n"
"leads to changes of 1 pointer. For example, with\n"
"initialization of q=s, we can get:\n");
for (q = s; q <= &s[ns - 1]; q++)
printf("q = %p, *q = %p: \"%s\"\n", (void *) q, (void *) *q,
*q);
putchar('\n');

return 0;
}

[Output for one implementation:

The original array has these contents
s @ 1df0: "Jan"
s @ 1df4: "Feb"
s @ 1df8: "Mar"
s @ 1dfc: "April"

p is a pointer to char, so incrementing it leads
to changes of 1 byte. For example, with
initialization of p=s, we can get:
@ 1df0: 112 J
@ 1df1: 141 a
@ 1df2: 156 n
@ 1df3: 0

q is a pointer to pointer to char, so incrementing it
leads to changes of 1 pointer. For example, with
initialization of q=s, we can get:
q = dff98, *q = 1df0: "Jan"
q = dff9c, *q = 1df4: "Feb"
q = dffa0, *q = 1df8: "Mar"
q = dffa4, *q = 1dfc: "April"
Apr 18 '07 #11
On Apr 17, 10:16 pm, Martin Ambuhl <mamb...@earthlink.netwrote:
>The original array has these contents
s @ 1df0: "Jan"
s @ 1df4: "Feb"
s @ 1df8: "Mar"
s @ 1dfc: "April"

p is a pointer to char, so incrementing it leads
to changes of 1 byte. For example, with
initialization of p=s, we can get:
@ 1df0: 112 J
@ 1df1: 141 a
@ 1df2: 156 n
@ 1df3: 0

q is a pointer to pointer to char, so incrementing it
leads to changes of 1 pointer. For example, with
initialization of q=s, we can get:
q = dff98, *q = 1df0: "Jan"
q = dff9c, *q = 1df4: "Feb"
q = dffa0, *q = 1df8: "Mar"
q = dffa4, *q = 1dfc: "April"
Thank You Martin,
It's beginning to make a lot more sense now.

Apr 18 '07 #12
On Apr 17, 10:16 pm, Martin Ambuhl <mamb...@earthlink.netwrote:

>
p is a pointer to char, so incrementing it leads

q is a pointer to pointer to char, so incrementing it

Martin,
Could you clear up one last confusing issue...( well, I guess, not
last, but confusing :-))

The reason this whole question arose was to understand *argv[] (in
main) and try and create an analagous situation to it.
On p 114 (K&R) it says *argv[].....is a pointer to an array of
character strings"
clarify, where does this fit in? I would guess that *argv[] under this
circumstance is type pointer to pointer to char? Which, if this is
true, should also be allowed to be written as **argv ? Not sure why it
is not thus written then.
Once again...thanks for taking the time to clear up something which I
guess all newbies struggle with.
Apr 18 '07 #13
mdh wrote:
>
The reason this whole question arose was to understand *argv[] (in
main) and try and create an analagous situation to it.
On p 114 (K&R) it says *argv[].....is a pointer to an array of
character strings"
clarify, where does this fit in? I would guess that *argv[] under this
circumstance is type pointer to pointer to char? Which, if this is
true, should also be allowed to be written as **argv ? Not sure why it
is not thus written then.
It often is. It's certainly my preferred form.

--
Ian Collins.
Apr 18 '07 #14
mdh wrote:
I would guess that *argv[] under this
circumstance is type pointer to pointer to char? Which, if this is
true, should also be allowed to be written as **argv ? Not sure why it
is not thus written then.
On Apr 18, 12:40 am, Ian Collins <ian-n...@hotmail.comwrote:
>
It often is. It's certainly my preferred form.

Ok...well that clears that up...thank you.

Apr 18 '07 #15

 8 posts views Thread by Gerald | last post: by 2 posts views Thread by Steve | last post: by 8 posts views Thread by Peter B. Steiger | last post: by 19 posts views Thread by gaga | last post: by 7 posts views Thread by Frank M. | last post: by 8 posts views Thread by ptek | last post: by 6 posts views Thread by Piotrek | last post: by 15 posts views Thread by Jess | last post: by 5 posts views Thread by ramu | last post: by 9 posts views Thread by Slain | last post: by reply views Thread by eddparker01 | last post: by reply views Thread by eddparker01 | last post: by 1 post views Thread by isladogs | last post: by reply views Thread by Trystan | last post: by reply views Thread by Trystan | last post: by 9 posts views Thread by anoble1 | last post: by reply views Thread by Romlus | last post: by 1 post views Thread by MikeCant | last post: by 2 posts views Thread by Usman55 | last post: by