Ankit Bhardwaj
Ankit Bhardwaj

Reputation: 89

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

Upvotes: 1

Views: 97

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310960

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].

Upvotes: 1

dbush
dbush

Reputation: 223749

This is not valid:

    int s[5]={10,1,2,3,4};
    int (*p)[10]=s;

Because you're initializing a variable of type int (*)[10] (a pointer to an array of int of size 10) with an expression of type int *. These types are not compatible.

While this is fine:

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

Because the type of the initializer matches the type of the variable.

Also, when printing pointer values, you should use the %p format specifier and cast the argument to void *. Mismatching format specifiers with their associated arguments triggers undefined behavior.

Upvotes: 2

Related Questions