简体   繁体   中英

Use of typecasting in pointer to an array

int s[4][2] = {1234,56,1212,33,1434,80,1312,78} ;   
int (*p)[2], i, j;    
int *pint;      
for(i=0;i<=3;i++)      
{
    p = s[i];    
    pint = (int*) p;    
    for(j=0;j<=1;j++) 
    {
        printf("%d ",*(pint+j));   
    }

    printf("\n");
}   

Here, p is a pointer to an array of 2 integers and p contains the address of the ith 1-D array. But why are we typecasting p to pint? And using pint for the rest of our program. Why can't we use p only instead of pint?

Also, I tried taking p instead of pint, but then it is printing address of 1-D array instead of elements. Why?

For starters it would be more correctly to write

pint = *p;

instead of

pint = (int*) p;    

And this expression statement

p = s[i];

is also wrong. s[i] has type int[2] that used in expressions is implicitly converted to an object of type int * . While the left side operand has type int ( * )[2] . So there is an attempt to assign a pointer of type int( * )[2] with an expression of type int * . However the types are incompatible.

You have to write either

p = &s[i];

or

p = s + i;

Of course there is no need to introduce a new pointer that to output elements of the array. However using an additional pointer you can simplify constructions.

Without introducing a new pointer the loop could look like

for ( i = 0; i < 4; i++ )      
{
    p = s + i;    

    for ( j = 0; j < 2; j++ ) 
    {
        printf( "%d ", *( *p + j ) );   
    }

    printf( "\n" );
}   

This quote from the C Standard will be helpful (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

Thus array s having type int[4][2] used in expressions except as an operand of the sizeof or & operations is converted to pointer to its first element of type int ( * )[2]

If to apply operator * to the pointer the type of the result object will be int[2] that is an array. Again in expressions it in turn is converted to pointer to its first element of type int * .

So expression *p has type int * . If it would be used in the sizeof operator then it had type int[2] .

One Dimension arrays:


int a[2] ; 

is equiavalent to:

int *a ;
a = malloc(sizeof(int) * 2);

Two Dimension arrays:


int a[4][2] ;

is equivalent to :

int **a ;
a = malloc(sizeof(int *)*4);
for ( i = 0 ; i < 2 ; ++i){
*(a+i) = malloc(sizeof(int)*2);
} 

How can it relate to your example:


int (*p)[2]; 

type of p : int **

EDIT:This is wrong


p is of type (*)[2]

int s[4][2] ;

type of s : int **

EDIT:s is type of (*)[2] not **


type of s[i] : int *
type of s[i][j] : int

Credit goes to the commentators, thanks.

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