Clarification needed on Pointers/Arrays

David Geary dmg at ssc-vax.UUCP
Sat Feb 25 03:34:16 AEST 1989


In Message-ID: <1436 at 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                  ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



More information about the Comp.lang.c mailing list