Pointer to a Single Dimension Array of Integers

In this section, you are going to learn

type ( *ptr ) [ size_of_array ];

An example is as below

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

int (*ptr)[10];

ptr = &a;

Pointer to an Array when incremented, increments by size of the array to which it is pointing to !

Pointer to an Array when decremented, decrements by size of the array to which it is pointing to !

Let us see how it is done. See below

  • Step 1 : Define a single dimension array

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  • Step 2 : Define a pointer to an array

int (*ptr)[10];
  • Step 3 : Let pointer to an array, point to single dimension array

ptr = &a;
  • Step 4 : Check pointer arithmetic

printf("Before Increment : ptr = %lx\n", (unsigned long int) ptr);

ptr++;

printf("After Increment : ptr = %lx\n", (unsigned long int) ptr);
  • See full program below

#include <stdio.h>

int main(void)
{
        int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        int (*ptr)[10];

        ptr = &a;

        printf("Before Increment : ptr = %lx\n", (unsigned long int) ptr);

        ptr++;

        printf("After Increment : ptr = %lx\n", (unsigned long int) ptr);

        return 0;
}
  • Output is as below

Before Increment : ptr = 7ffc4ed5b130
After Increment  : ptr = 7ffc4ed5b158

Observe that difference is 40 !

  • Which is equal to 10 Integers

When Pointer to an Array is passed as argument, Prototype of function should match the type properly !

Let us see how it is done. See below

  • Step 1 : Define a single dimension array

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  • Step 2 : Define a pointer to an array

int (*ptr)[10];
  • Step 3 : Let pointer to an array, point to single dimension array

ptr = &a;
  • Step 4 : Pass ptr as argument to function fun

fun(ptr);
  • Step 5 : Define function fun

void fun( int (*p)[10] )
{
}
  • See full program below

#include <stdio.h>

void fun( int (*p)[10] )
{
}

int main(void)
{
        int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        int (*ptr)[10];

        ptr = &a;

        fun(ptr);

        return 0;
}

When Pointer to an Array is passed as argument by call by reference, Prototype of function should match the type properly !

Let us see how it is done. See below

  • Step 1 : Define a Double dimension array

int a[3][5] = {
        {1, 2, 3, 4, 5},
        {10, 20, 30, 40, 50},
        {100, 200, 300, 400, 500}
      };
  • Step 2 : Define a pointer to an array

int (*ptr)[5];
  • Step 3 : Let pointer to an array, point to single dimension array

ptr = &a[0];
  • Step 4 : Pass ptr as argument to function fun. Call by reference

fun(&ptr);
  • Step 5 : Define function fun

void fun(int (**p)[5])
{
        for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 5; j++) {
                        printf("%d ", (*p)[i][j]);
                }
                printf("\n");
        }
}

This is easy to understand ! Let us derive the rules

  • Rule 1 : Base rule in main

ptr = &a[0];
  • Rule 2 : Base rule in fun

p = &ptr
  • Rule 2 : Move & from RHS to LHS. This becomes * on LHS

*p = ptr
  • Rule 3 : Replace ptr referring to Rule 1

*p = &a[0]
  • Rule 4 : Move & from RHS to LHS. This becomes * on LHS

**p = a[0]
  • Rule 5 : * and [ ] can be used interchangeably

(*p)[0] = a[0]
  • Rule 6 : * and [ ] can be used interchangeably

p[0][0] = a[0]
  • Rule 7 : * and [ ] can be used interchangeably

p[0][0] = &a[0][0]
  • Rule 8 : Move & from RHS to LHS. This becomes * on LHS

(*p)[0][0] = a[0][0]
  • Rule 9 : Extending Rule 8

(*p)[i][j] = a[i][j]
  • See full program below

#include <stdio.h>

void fun(int (**p)[5])
{
        for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 5; j++) {
                        printf("%d ", (*p)[i][j]);
                }
                printf("\n");
        }
}

int main(void)
{
        int a[3][5] = {
                {1, 2, 3, 4, 5},
                {10, 20, 30, 40, 50},
                {100, 200, 300, 400, 500}
        };

        int (*ptr)[5];

        ptr = &a[0];

        fun(&ptr);

        return 0;
}
  • Output is as below

1 2 3 4 5
10 20 30 40 50
100 200 300 400 500

We can use pointer to an array directly inorder to print the contents of array to which it is pointing to !

Let us see how it is done. See below

  • Step 1 : Define a single dimension array

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  • Step 2 : Define a pointer to an array

int (*ptr)[10];
  • Step 3 : Let pointer to an array, point to single dimension array

ptr = &a;

We can derive other rules from this base rule !

  • Rule 1 : Base rule

ptr = &a;
  • Rule 2 : Move & from RHS to LHS. This becomes * on LHS

*ptr = a
  • Rule 3 : a is also equals to &a[0]

*ptr = &a[0]
  • Rule 4 : *ptr is equal to ptr[0]

ptr[0] = &a[0]
  • Rule 5 : Move & from RHS to LHS. This becomes * on LHS

(*ptr)[0] = a[0]
  • Rule 6 : (*ptr)[0] is equal to ptr[0][0]

ptr[0][0] = a[0]
  • Rule 7 : Extending Rule 5

(*ptr)[i] = a[i]
  • Step 4 : Access individual integers using (*ptr)[i]

for (int i = 0; i < 10; i++) {
        printf("%d\n", (*ptr)[i]);
}
  • See full program below

#include <stdio.h>

int main(void)
{
        int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        int (*ptr)[10];

        ptr = &a;

        // Print individual integers
        for (int i = 0; i < 10; i++) {
                printf("%d\n", (*ptr)[i]);
        }

        return 0;
}
  • Output is as below

0
1
2
3
4
5
6
7
8
9

We can use pointer to an array directly inorder to print the contents of array to which it is pointing to !

Let us see how it is done. See below

  • Step 1 : Define a single dimension array

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  • Step 2 : Pass address of array a as an argument to function fun

fun(&a, sizeof(a));
  • Step 3 : Define function fun

void fun(int (*p)[10], int size)
{

}

Note the function definition !

  • Since first argument is passed as address of array a, prototype must have pointer to an array in first parameter

  • Step 4 : Let us write the code to access individual integers of single dimension array inside function fun

void fun(int (*p)[10], int size)
{
        for (int i = 0; i < size; i++) {
                printf("%d\n", (*p)[i]);
        }

        for (int i = 0; i < size; i++) {
                printf("%d\n", p[0][i]);
        }
}

This is easy to understand ! Let us derive the rules

  • Rule 1 : Base rule

p = &a

Where,

  • LHS p is a variable on stack of function fun fun

  • RHS &a is actual argument passed to function fun

  • Rule 2 : Move & from RHS to LHS. This becomes * on LHS

*p = a
  • Rule 3 : a is also equals to &a[0]

*p = &a[0]
  • Rule 4 : Move & from RHS to LHS. This becomes * on LHS

**p = a[0]
  • Rule 5 : * and [ ] can be used interchangeably

(*p)[0] = a[0]
  • Rule 6 : * and [ ] can be used interchangeably

p[0][0] = a[0]
  • Rule 7 : Extending Rule 5

(*p)[i] = a[i]
  • Rule 8 : Extending Rule 5

p[0][i] = a[i]
  • See full program below

#include <stdio.h>

void fun(int (*p)[10], int size)
{
        int *sp;

        sp = *p;

        for (int i = 0; i < size; i++) {
                printf("%d ", sp[i]);
        }

        printf("\n");

        for (int i = 0; i < size; i++) {
                printf("%d ", (*p)[i]);
        }

        printf("\n");

        for (int i = 0; i < size; i++) {
                printf("%d ", p[0][i]);
        }

        printf("\n");
}

int main(void)
{
        int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        fun(&a, sizeof(a) / sizeof(a[0]) );

        return 0;
}
  • Output is as below

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
  • Step 1 : Define a double dimension array of integers

int a[3][5] = {
                {1, 2, 3, 4, 5},
                {10, 20, 30, 40, 50},
                {100, 200, 300, 400, 500}
              };
  • Step 2 : Define a pointer to an array of single dimension

int (*ptr)[5];

Here everytime ptr increments, it increments by 5 Integers (equal to 20 Bytes) !

  • Step 3 : Let the pointer to point to Single dimension array inside a Double dimension array

ptr = &a[0];
  • Step 4 : Access individual integers using ptr

for (int i = 0; i < 3; i++)
{
        for (int j = 0; j < 5; j++)
        {
                printf("%d ", ptr[i][j]);
        }
        printf("\n");
}

This is easy to understand ! Let us derive the rules

  • Rule 1 : Base rule

ptr = &a[0];
  • Rule 2 : Move & from RHS to LHS. This becomes * on LHS

*ptr = a[0];
  • Rule 3 : a[0] is equal to &a[0][0]

*ptr = &a[0][0];
  • Rule 4 : Move & from RHS to LHS. This becomes * on LHS

**ptr = a[0][0];
  • Rule 5 : * and [ ] can be used interchangeably

*ptr[0] = a[0][0]
  • Rule 6 : * and [ ] can be used interchangeably

ptr[0][0] = a[0][0]
  • Rule 7 : Extending Rule 6

ptr[i][j] = a[i][j]
  • See full program below

#include <stdio.h>

int main(void)
{
        int a[3][5] = {
                        {1, 2, 3, 4, 5},
                        {10, 20, 30, 40, 50},
                        {100, 200, 300, 400, 500}
                     };

        int (*ptr)[5];

        ptr = &a[0];

        for (int i = 0; i < 3; i++)
        {
                for (int j = 0; j < 5; j++)
                {
                        printf("%d ", ptr[i][j]);
                }
                printf("\n");
        }

        return 0;
}
  • Output is as below

1 2 3 4 5
10 20 30 40 50
100 200 300 400 500
  • Step 1 : Allocate a block of memory in Heap

int *a;

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

Allocates 15 Integers (60 Bytes of memory in Heap)

  • Step 2 : Assign User Data in Heap memory

int arr0[] = {1, 2, 3, 4, 5};
int arr1[] = {10, 20, 30, 40, 50};
int arr2[] = {100, 200, 300, 400, 500};

memset(a, 0, 60);
memcpy(a, arr0, 5 * sizeof(int) );
memcpy(a + 5, arr1, 5 * sizeof(int) );
memcpy(a + 10, arr2, 5 * sizeof(int) );

We have split the Heap into 3 blocks, with each block containing 5 Integers

  • Step 3 : Let ptr point to block of memory in Heap

ptr = (int (*)[5])a;

Note the typecasting done !

Key is to remember that, ptr should point to block of continuous memory for it to access User data properly !

  • Step 4 : Access the memory block in Heap using ptr

for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 5; j++) {
                printf("%d ", ptr[i][j]);
        }
        printf("\n");
}

Everytime ptr is indexed with i it points to block of 5 Integers

  • ptr[0] points to Byte 0 in Heap

  • ptr[1] points to Byte 20 in Heap

  • ptr[2] points to Byte 40 in Heap

  • Step 6 : Free Heap memory after use

free(a);
  • See full program below

#include <string.h>
#include <stdlib.h>

int main(void)
{
        int *a;
        int arr0[] = {1, 2, 3, 4, 5};
        int arr1[] = {10, 20, 30, 40, 50};
        int arr2[] = {100, 200, 300, 400, 500};

        int (*ptr)[5];

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

        memset(a, 0, 60);

        memcpy(a, arr0, 5 * sizeof(int) );
        memcpy(a + 5, arr1, 5 * sizeof(int) );
        memcpy(a + 10, arr2, 5 * sizeof(int) );

        ptr = (int (*)[5])a;

        for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 5; j++) {
                        printf("%d ", ptr[i][j]);
                }
                printf("\n");
        }

        free(a);

        return 0;
}