What is the difference between pointer to array and pointer to pointer?

假装没事ソ 提交于 2019-12-06 13:41:35

The trick is the array-pointer-decay: When you mention the name of an array, it will decay into a pointer to its first element in almost all contexts. That is num is simply an array of three arrays of three integers (type = int [3][3]).

Lets analyse the expression *(*(num + 1) + 2).

When you mention num in the expression *(num + 1), it decays into a pointer to its first element which is an array of three integers (type = int (*)[3]). On this pointer pointer arithmetic is performed, and the size of whatever the pointer points to is added to the value of the pointer. In this case it is the size of an array of three integers (that's 12 bytes on many machines). After dereferencing the pointer, you are left with a type of int [3].

However, this dereferencing only concerns the type, because right after the dereferencing operation, we see expression *(/*expression of type int[3]*/ + 2), so the inner expression decays back into a pointer to the first array element. This pointer contains the same address as the pointer that results from num + 1, but it has a different type: int*. Consequently, the pointer arithmetic on this pointer advances the pointer by two integers (8 bytes). So the expression *(*(num + 1) + 2) yields the integer element at an offset of 12 + 8 = 20 bytes, which is the sixth integer in the array.


Regarding your question about the call of fun(), that call is actually broken, and only works because your teacher did not include the arguments in the forward declaration of fun(). The code

int fun(int* arg);

int main() {
    int num[3][3] = ...;
    ...
    fun(num);
}

would have generated a compile time error due to the wrong pointer type. The code of your teacher "works", because the pointer to the first array in num is the same as the pointer to the first element of the first array in num, i. e. his code is equivalent to

int fun(int* arg);

int main() {
    int num[3][3] = ...;
    ...
    //both calls are equivalent
    fun(num[0]);
    fun(&num[0][0]);
}

which would compile without error.

This example shows a matrix, pointers to the first integers of arrays, and pointer to pointer

#include<stdio.h>
int fun(int (*p)[3]);  /* p is pointer to array of 3 ints */
int main()
{
    /* matrix */
    int num[3][3]={{23,32,478},{55,0,56},{25,13, 80}};
    /* three pointers to first integer of array */
    int *pnum[3] = {num[0], num[1], num[2]};
    /* pointer to pointer */
    int **ppnum = pnum;
    printf("%d\n", *(*(num+1)+2));
    fun(num);
    printf("%d\n", *(*(num+1)+2));
    pnum[1][2] = 2;
    printf("%d\n", *(*(num+1)+2));
    ppnum[1][2] = 3;
    printf("%d\n", *(*(num+1)+2));
    return 0;
}
int fun(int (*p)[3])
{
    p[1][2]=1;
    return 0;
}

You do not actually need any pointers to print anything here.

Your int num[3][3] is actually an array of three elements, each of which is an array of three integers. Thus num[0][0] = 23, num[1][1] = 0, and so on. Thus you can say printf("%d", num[0][0]) to print the first element of the array.

Pointer to variable:

Pointer is variable which stores the address( of a variable). Every one know that.


Pointer to Array:

An array is a variable which has the starting point(address) of group of same objects.

And the pointer is a variable which stores the starting point(address) of an Array.

For example:

int iArray[3];

iArray is a variable which has an address value of three integers and the memory is allocated statically. And the below syntax is provided in a typical programming languages.

// iArray[0] = *(iArray+0);
// iArray[1] = *(iArray+1);
// iArray[2] = *(iArray+2);

In the above the iArray is a variable through which we can access the three integer variables, using any of the syntax mentioned above.

*(iArray+0); // Here iArray+0 is the address of the first object. and * is to dereference *(iArray+1); // Here iArray+1 is the address of the second object. and * is to dereference

So simple, what is there to confuse.


The below lines are for your understanding

int iArray1[3];
int iArray2[3][3];

int *ipArray = 0;

ipArray = iArray1;        // correct
ipArray = iArray2[0];     // correct
ipArray = iArray2[2];     // correct
int **ippArray = iArray2; // wrong

As per the above last line, compiler will not take it as a valid assignment. So **p is not used.

Pointer arthmatic cannot be applied on double arrays because of the way memory is allocated.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!