Search code examples
arrayscpointersprintfpointer-to-array

What is the difference between int (*p)[10]=s and int (*o)[5]=&s?


On basis of the convention int (*o)[5]=&s; is the right way for a pointer o to point an array having 5 elements.

We can also write this s in this statement

int (*p)[10]=s; 

but why preferring

&s at int (*o)[5]=&s; 

as both of them return the same output.

#include <stdio.h>
int main()
{
        int s[5]={10,1,2,3,4};
        int (*p)[10]=s;
        printf("%d\n",*p);
        printf("%d\n",**p);
        printf("%d\n",&s);
        
        printf("\n");

        int (*o)[5]=&s;
        printf("%d\n",*o);
        printf("%d\n",**o);
        printf("%d",&s);
    
        return 0;
}

Output of this program is:

-593812272
10
-593812272

-593812272
10
-593812272

Solution

  • This line

    int (*p)[10]=s;
    

    is incorrect. The initializer has the type int * due to the implicit conversion of the array designator s to a pointer to its first element. And the two pointers in the left hand side and in the right hand are not compatible. So the compiler should issue a message.

    This line

    int (*o)[5]=&s;
    

    is correct. The initializer has the type int ( * )[5] that is the same type of the initialized pointer o.

    Pay attention to that to output a value of a pointer you have to use the conversion specifier %p. Otherwise using the conversion specifier %d to output a pointer invokes undefined behavior.

    So for example instead of these calls

    printf("%d\n",*o);
    //...
    printf("%d",&s);
    

    you have to write

    printf("%p\n", ( void *)*o);
    //...
    printf("%p\n", ( void * )&s);
    

    The expression *o yields value of the array s that is in turn is implicitly converted to a pointer to its first element.

    The values of the expression *o and of the expression &s are the same because it is the address of the extent of memory occupied by the array. But their types are different. The first expression used as an argument of the call of printf has the type int * while the second expression has the type int ( * )[5].