Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!fluke!ssc-vax!dmg From: dmg@ssc-vax.UUCP (David Geary) Newsgroups: comp.lang.c Subject: Re: Clarification needed on Pointers/Arrays Message-ID: <2518@ssc-vax.UUCP> Date: 24 Feb 89 17:34:16 GMT Organization: Boeing Aerospace Corp., Seattle WA Lines: 112 In Message-ID: <1436@etive.ed.ac.uk>, S. Manoharan writes: > I need to reason the likely outcome of > /* LINE 1 */ and /* LINE 2 */ > main() > { > static char *a[] = { "123456789", "bull", "fred", "foo" }; > /* array of char-pointers */ Ok, a is "an array of pointers to char". a[0] holds the address where the '1' resides in the string "123456789", a[1] holds the address where the 'b' in "bull" resides in memory, etc. > > printf("Entries %d\n",sizeof(a)/sizeof(char *)); > foo1(a); > foo2(a); When you call foo1() and foo(2), you are actually doing: foo1(&a[0]); foo2(&a[0]); In the context of an argument to a function, the name of an array is the same as the address of the initial element of the array. Furthermore, realize that if a[0] is a pointer to char (which it is), then &a[0] is a pointer to a pointer to char, (char **) > } > > foo1(b) > char *b; NO!! You didn't pass char *, you passed char ** - see above. > { > int i; > > printf("Entries %d\n",sizeof(b)/sizeof(char *)); > /* LINE 1 */ for ( i = 0; i < 10; ++i ) printf("%d: %c\n",i,b+i); You are printing b+i as a character. b holds the ADDRESS of a[0] in main. Therefore, you are trying to print the address of a[0] plus a constant (probably something ugly like: 0xfffe0 - a big number) as a character. So, you will get garbage. > } > > foo2(b) > char *b[]; Now this is better. b is an array of pointers to char, which is what you passed from main(). Notice that the compiler treats this declaration the same as: char **b; > { > int i; > /* LINE 2 */ printf("Entries %d\n",sizeof(b)/sizeof(char *)); > for ( i = 0; i < 4; ++i ) printf("%d: %s\n",i,b[i]); b is an array of pointers to char, so b[i] is a pointer to char, so this will work correctly. > } > >-------- > Output of the program was: > > Entries 4 > Entries 1 > 0: ^P <--- Expected ... 1 No, expect garbage, see above. > 1: ^Q <--- Expected ... 2 > 2: ^R <--- Expected ... 3 > 3: ^S <--- Expected ... 4 > 4: ^T <--- Expected ... 5 > 5: ^U <--- Expected ... 6 > 6: ^V <--- Expected ... 7 > 7: ^W <--- Expected ... 8 > 8: ^X <--- Expected ... 9 > 9: ^Z > Entries 1 <--- Expected ... 4 > 0: 123456789 > 1: bull > 2: fred > 3: foo > --- Here's a working version of foo1(): foo1(b) char *b[]; /* or char **b - same difference */ { int i; char *p = *b; /* b holds the address of a[0] from main. *b gives whatever value is at the address stored in b, namely, a[0], which is the address of the '1' in the string "123456789" in main(). */ for(i=0; i < 9; ++i) /* There are only 9 chars in string */ printf("%d: %c\n", i, *(p+i)); } -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, ~ ~ #define Seattle RAIN ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~