Home > Back-end >  How do Array Pointers behave?
How do Array Pointers behave?

Time:07-22

I was trying to write the code for storing multiplication table in array.

First I wrote the following code.

#include<stdio.h>

void Multiplication(int arr[][10], int num,int size);

int main(){
    int arr[3][10];
    Multiplication(&arr[0],2,3);
    Multiplication(&arr[1],7,3);
    Multiplication(&arr[2],9,3);
    for(int i=0;i<3;i  ){
        printf("\n\nMultiplication Table of %d\n\n",arr[i][0]);
        for(int j=0;j<10;j  ){
            printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]);
        }
    }
    return 0;
}

void Multiplication(int arr[][10], int num, int size){
    for(int j=0;j<size;j  ){
        for(int i=0;i<10;i  ){
            arr[j][i] = num * (i 1);
        }
    }
}

When I was checking whether there is any reduntant part, I removed a little bit of pieces.

#include<stdio.h>

void Multiplication(int *arr, int num,int size);

int main(){
    int arr[3][10];
    Multiplication(arr[0],2,3);
    Multiplication(arr[1],7,3);
    Multiplication(arr[2],9,3);
    for(int i=0;i<3;i  ){
        printf("\n\nMultiplication Table of %d\n\n",arr[i][0]);
        for(int j=0;j<10;j  ){
            printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]);
        }
    }
    return 0;
}

void Multiplication(int *arr, int num,int size){
        for(int i=0;i<10;i  ){
            arr[i] = num * (i 1);
        }
}

Now, I noticed that &arr[0] and arr[0] are behaving same? I wanna know why is it so?

CodePudding user response:

The following is the question asked:

I noticed that &arr[0] and arr[0] are behaving same? I wanna know why is it so?

We have

int arr[3][10];

arr[0] is a int[10], which is to say an array of 10 int values.

But it's being treated as a pointer. When an array is treated as a pointer, it produces a pointer to the first element of the array. So this means arr[0] is automatically converted to a int* pointing to the first element of the first row of arr when necessary.

&arr[0] means &(arr[0]). It produces a int(*)[10] pointing to the first row of arr.

To recap,

  • arr[0] is a int[10] which degrades to a int*.

    It points to the first element of the first row of arr.

  • &arr[0] is a int(*)[10].

    It points to the first row of arr.

So, arr[0] is NOT equivalent to &arr[0], contrary to your assertion.

And this lack of equivalence is why you had to change from &arr[0] when you when you had int arr[][10] (which means int (*arr)[10] a parameter), to arr[10] when you had int *arr as the parameter.

CodePudding user response:

The both programs are incorrect.

You declared a two dimensional array

 int arr[3][10];

So expressions like this arr[0], arr[1], arr[2] have the array type int[10]. That is they produce the first "row", the second "row" and the third "row" of the two-dimensional array.

In the first program you are calling the function Multiplication like

Multiplication(&arr[0],2,3);
Multiplication(&arr[1],7,3);
Multiplication(&arr[2],9,3);

and within the function there are two nested loops

void Multiplication(int arr[][10], int num, int size){
    for(int j=0;j<size;j  ){
        for(int i=0;i<10;i  ){
            arr[j][i] = num * (i 1);
        }
    }
}

according to the argument specified for the parameter size the function deals with a two dimensional array with three elements (rows) of the array type int[10] using a pointer to the first element of the array. As a result for the argument expressions &arr[1] and &arr[2] there is an access to the memory beyond the original two dimensional array.

You may consider these calls

Multiplication(&arr[0],2,3);
Multiplication(&arr[1],7,3);
Multiplication(&arr[2],9,3);

like

Multiplication( arr, 2, 3 );
Multiplication( arr   1, 7, 3 );
Multiplication( arr   2, 9, 3 );

The array designator arr is implicitly converted to a pointer to its first element (row) of the type int ( * )[10].

As you are setting only one "row" within the array then the function can be declared and defined the following way

void Multiplication(int arr[][10], int num ){
    for(int j=0;j < 10;j  ){
        ( *arr )[j]= num * (j 1);
    }
}

and called like

Multiplication( arr, 2 );
Multiplication( arr   1, 7 );
Multiplication( arr  2, 9 );

Of you want to set elements of a sub-array then the function can be defined the way it is defined initially but called like

Multiplication( arr, 2, 3 );
Multiplication( arr   1, 7, 2 );
Multiplication( arr  2, 9, 1 );

In the second program the function is declared like

void Multiplication(int *arr, int num,int size){
        for(int i=0;i<10;i  ){
            arr[i] = num * (i 1);
        }
}

and you are calling it like

Multiplication(arr[0],2,3);
Multiplication(arr[1],7,3);
Multiplication(arr[2],9,3);

But within the function the parameter size is not used. There is used the magic number 10. And the passed argument 3 does not make a sense.

You should declare the function like

void Multiplication(int *arr, int num,int size){
        for(int i=0;i<size;i  ){
            arr[i] = num * (i 1);
        }
}

and call it like

Multiplication(arr[0],2,10);
Multiplication(arr[1],7,10);
Multiplication(arr[2],9,10);
  • Related