简体   繁体   中英

Is array the pointer to the first element, if yes…?

...then why is the code below give same value (meatballs) for address and the actual content? And how to make sense of %d value of meatballs, is it random?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          meatballs);

    return 0;

}
  1. meatballs is an array, and it has type int[5] . However C doesn't allow passing arrays by value, so array decays into pointer for function call. This is equivalent of pointer to first element of array &meatballs[0] , and it has type int* .

  2. &meatballs is a pointer to an array, and it has type int(*)[5] . Since it's a pointer it can be passed to a function.

As you can see, both 1. and 2. return same address, but they have different types: pointer to integer array vs pointer to single integer.

Note: Types void* and int* don't necessarily have the same representation (1) , and for %p only valid type is void* (2) or you will get undefined behaviour (3) . Always convert pointer to void* when printing addresses:

printf("%p %p", (void*)meatballs, (void*)&meatballs);
  1. Last situation is same as first, but you are using wrong type specifier %d . Resulting type is again int* as in case 1, but it is interpreted as int . This is clear undefined behaviour , and output is garbage.

To print integer array element, use any of the following methods:

printf("%d %d %d", meatballs[i], *(meatballs + i), *meatballs);

First two will print array element at index i , and last will print first element. I recommend using the meatballs[i] in most cases, as it's most clear.


References to C standard (draft):

  1. N1570, 6.2.5 paragraph 28

    A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. 48) ... ...Pointers to other types need not have the same representation or alignment requirements.

  2. N1570, 7.21.6 paragraph 8

    p The argument shall be a pointer to void . ...

  3. N1570, 7.21.6 paragraph 9

    ... If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

You have to use the unary dereference operator * , so that the actual value is shown as %d expects an integer.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          *meatballs);

    return 0;

}

Look at the last parameter: *meatballs . This code actually prints 1 as value and is the first element in your array. So your guess is right and it is only a bug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM