简体   繁体   中英

Double Pointer to Array in C

Below is a code snippet and the outputs:

int main() 
{
    int A[2][3] = {{1100, 1200, 1300}, {1400, 1500, 1600}};
    int (*p)[3], (**q)[3];
    p = A;
    q = A;
    printf("*p is : %d\n", *p);
    //Output : *p is : -547221600
    printf("*q is : %d", *q);//Why ?  
    //Output : *q is : 1100 
}

p is a pointer to integer array of size 3. *p + i points to ith array in A ie A[i]. What would happen if instead I use double pointers ( q in the above code). I am unable to understand that why *q gives 1100 as the value.

For starters this assignment

q = A;

is incorrect because the left operand (having the type int ( ** )[3] ) and the right operand (having the type int ( * )[3] after the implicit conversion of the array designator to a pointer to its first element) have different types and there is no implicit conversion between the types.

The compiler can issue an error like this

error: assignment to ‘int (**)[3]’ from incompatible pointer type ‘int (*)[3]’

You could write instead

q = &p;

In this call of printf

printf("*p is : %d\n", *p);

there is used an incorrect argument. The type of the expression *p is int[3] . So in fact you are trying to output a pointer (due to implicit conversion of the array designator to a pointer to its first element) using the conversion specifier %d that is designed to output integers.

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    int A[2][3] = {{1100, 1200, 1300}, {1400, 1500, 1600}};
    int (*p)[3], (**q)[3];
    p = A;
    q = &p;
    
    printf( "A  is : %p\n", ( void * )A );
    printf( "*p is : %p\n", ( void * )*p );
    printf( "*q is : %p\n", ( void * )*q);
    
    return 0;
}

Its output might look like

A  is : 0x7ffdb1c214e0
*p is : 0x7ffdb1c214e0
*q is : 0x7ffdb1c214e0

That is the first call of printf output the initial address of the first element A[0] (of the type int[3]) of the two-dimensional array.

The second call of printf outputs the address of the first element of the first "row" of the two-dimensional array that is &A[0][0].

The third call of printf outputs the value stored in the pointer p that is the address of the first "row" of the two-dimensional array A.

If you want to output the first elements of the array A using the pointers then the program can look the following way.

#include <stdio.h>

int main(void) 
{
    int A[2][3] = {{1100, 1200, 1300}, {1400, 1500, 1600}};
    int (*p)[3], (**q)[3];
    p = A;
    q = &p;
    
    printf( "**p  is : %d\n", **p );
    printf( "***q is : %d\n", ***q);
    
    return 0;
}

Now the program output is

**p  is : 1100
***q is : 1100

p is a pointer to integer array of size 3.

Correct.

*p + i points to ith array in A ie A[i].

Incorrect. p + i would be a pointer to an array.

When you indirect through the pointer to array, the result is an array, and when you add an integer to an array, the array decays to pointer to element of that array and since *p is an array of integers, the decayed pointer points to an integer element of the array. Thus, the result of *p + i is a pointer to an integer (i'th sibling of the first element of the first array).

What would happen if instead I use double pointers (q in the above code).

I assume that by substituted above code, you mean *q + i .

If you have a pointer to a pointer to an array, then indirecting through the pointer results in a pointer to an array. Adding an integer to pointer to an array gives you pointer to an array that is a sibling.


 q = A;

This assignment is ill-formed in C++. An array of arrays of integers is not convertible to a pointer to pointer to an array.

 printf("*p is: %d\n", *p); printf("*q is: %d", *q);//Why?

%d is an invalid format specifier for int* as well as for a int (*)[3] . By using invalid format specifier, the behaviour of this program is undefined. That explains all of the behaviour.

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