Pointers and arrays in c

POINTERS AND ARRAYS:
What is an array?
An array is a data structure consisting of elements of similar data type.  The elements of an array are stored in consecutive memory locations.

How to declare an array?
Below is the template for array declaration.
datatype  name[number of elements];
          int   num[10];
Here, num is array of 10 integers.

How to access array elements?
Array indices are used to access array elements.  And the array index starts from zero.
      int arr[5] = {1, 2, 3, 4, 5};
arr[0] gives us the element at the 0th index in the array arr.  Let us try to read the array elements one by one.
arr[0] is 1 
arr[1] is 2 
arr[2] is 3 
arr[3] is 4 
arr[4] is 5 

How to access array elements using pointers?
To access array elements, assign the base address of array to the pointer.
     int *ptr;
     int arr[5] = {10, 20, 30, 40, 50};
     ptr = &arr[0];
Now, the pointer refers to the address of first element in the array arr.

*(ptr + 0) refers to the content of arr[0]

Then, *(ptr + i) refers to the content of arr[i].  So, the element at the array index i can be access by dereferencing the pointer (ptr + i).
ie. *(ptr + i) <=> arr[i]

How to write values in an array using pointers?
To write values in an array using pointers, assign the base address of array to pointer.  Then, assing value to the object refereced by pointer as shown below.
*(ptr + 0) = 100;
*(ptr + 1) = 200;
*(ptr + 2) = 300;
*(ptr + 3) = 400;
*(ptr + 4) = 500;

So, we have updated the array elements using pointers and the element in the array arr are as follows.
     arr[5] = {100, 200, 300, 400, 500};

Below program explains how to read values from an array and write values to array using pointers.


  #include <stdio.h>
  int main() {
        int i, arr[5], input;
        printf("Enter array inputs:\n");
        for (i = 0; i < 5; i++) {
                printf("arr[%d]: ", i);
                scanf("%d", &input);
                /* assigning values to array elements using pointers */
                *(arr + i) = input;
        }

        printf("\nReading array elements using pointer:\n");
        for (i = 0; i < 5; i++) {
                printf("arr[%d]: %d\n", i, *(arr + i));
        }
        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter array inputs:
  arr[0]: 10
  arr[1]: 20
  arr[2]: 30
  arr[3]: 40
  arr[4]: 50

  Reading array elements using pointer:
  arr[0]: 10
  arr[1]: 20
  arr[2]: 30
  arr[3]: 40
  arr[4]: 50



How to access two dimensional array using pointers?
Consider the following two dimensional array.
int num[2][2] = {{1, 2}, {3, 4}};

Pointer notation           Subscript notation            Value
**num                             num[0][0]                          1
*(*num + 1)                     num[0][1]                           2
*(*(num + 1))                   num[1][0]                          3
*(*(num + 1) + 1)              num[1][1]                          4

Using the above pointer notation, we can access two dimensional array using pointers.

How to write values into a two dimensional array using pointers?
**num                   = 10;
*(*num + 1)           = 20;
*(*(num + 1))         = 30;
*(*(num + 1) + 1)   = 40;

So, we have updated the values of a two dimensional array.  And the elements in the array num are as follows.
     num[2][2] = {{10, 20}, {30, 40}};

Below program explains how to read values from a multidimensional array and write values to a multidimensional array.


  #include <stdio.h>
  int main() {
        int i, j, num[2][2] = {{1, 2}, {3, 4}};
        printf("Reading two dimensional array using pointer:\n");
        for (i = 0; i < 2; i++) {
                for (j = 0; j < 2; j++) {
                        printf("num[%d][%d]: %d\n", i, j, *(*(num + i) + j));
                }
        }

        /* writing values to a 2d array */
        for (i = 0; i < 2; i++) {
                for (j = 0; j < 2; j++) {
                        *(*(num + i) + j) = num[i][j] + 100;
                }
        }

        printf("\nReading the updated values in 2d array using pointer:\n");
        for (i = 0; i < 2; i++) {
                for (j = 0; j < 2; j++) {
                        printf("num[%d][%d]: %d\n", i, j, *(*(num + i) + j));
                }
        }

        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Reading two dimensional array using pointer:
  num[0][0]: 1
  num[0][1]: 2
  num[1][0]: 3
  num[1][1]: 4

  Reading the updated values in 2d array using pointer:
  num[0][0]: 101
  num[0][1]: 102
  num[1][0]: 103
  num[1][1]: 104


Function pointers

Pointer to function in c with examples:

What is function pointer?
Every function has an address.  We can assign the address of functions to pointers.  Then those pointers are called pointers to functions.  Pointers to function is also called as function pointers.

How to declare function pointer?
Below is the declaration of a function pointer.
        int          (  *func_ptr  )             (int)
  <return type> (* <pointer name> ) (argument type)
Here, "func_ptr" is a pointer to a function whose return type is integer and it takes an integer argument.

How to get the address of a function?
Address of a function can be obtained from the function name.  The below program illustrates how to print/get address of a function.


  #include <stdio.h>
  int add(int a, int b) {
        return (a+b);
  }

  int main() {
        printf("address of function add(): 0x%x\n", (int)add);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  address of function add(): 0x80483c4



How to initialize function pointer?
Function pointer can be initialized by assigning a function name to it.  The below program explains how to initialize function pointers.


  #include <stdio.h>
  /* finds the difference of given two numbers */
  int sub(int a, int b) {
        return (a - b);
  }

  int main() {
        int num1, num2, res;
        int (*fptr) (int, int); // function pointer declaration

        /* get the inputs from the user */
        printf("Enter your first number:");
        scanf("%d", &num1);
        printf("Enter your second number:");
        scanf("%d", &num2);

        /* assigning address of function to pointer */
        fptr = sub; // initializing function pointer

        /* invokes sub() function using function pointer */
        res = (*fptr)(num1, num2);

        /* printing the result */
        printf("Result: %d\n", res);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter your first number:120
  Enter your second number:72
  Result: 48



How to invoke a function using function pointer?
Assign the address of a function to a pointer(function pointer).  Invoke the original function using the function pointer as shown below.  Pass arguments to function pointer if necessary.


  #include <stdio.h>

  /* prints hello world */
  void withoutArgs() {
        printf("Hello world\n");
        return;
  }

  /* prints the given string */
  void withArgs(char *str) {
        printf("%s\n", str);
        return;
  }

  int main() {
        void (*fptr_noArgs)(); // function pointer with no args
        void (*fptr_withArgs)(char *); // function pointer with args
        char str[] = "Hello Friend!!";

        /* function pointer initialization */
        fptr_noArgs   = withoutArgs;
        fptr_withArgs = withArgs;

        /* invoking functions using function pointers */
        (*fptr_noArgs)();  // no argument is passed
        (*fptr_withArgs)(str); // a string is passes as argument
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out 
  Hello world
  Hello Friend!!



How to pass function pointer as argument in c?
Assign address of a function to a pointer.  Pass the value of the function pointer as argument.  Below program explains how to pass function pointer as argument.


  #include <stdio.h>

  /* prints the result(sum of two numbers */
  void printMsg(int res) {
        printf("Sum of given two numbers is %d\n", res);
        return;
  }

 /* 
  * Adds the given number and prints the result.
  * Here, the third argument is pointer to function
  * and the parameter to function pointer is an integer
  */
  void add(int a, int b, void (*fptr)(int)) {
        int res = a + b;
        /* calling printMsg using function pointer */
        (*fptr)(res);
        return;
  }

  int main() {
        int num1, num2, res;

        /* get the inputs from the user */
        printf("Enter your first input : ");
        scanf("%d", &num1);
        printf("Enter your second input: ");
        scanf("%d", &num2);

        /*
         * passed the input values and 
         * address of the function "printMsg"
         * as argument
         */
        add(num1, num2, printMsg);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter your first input : 105
  Enter your second input: 205
  Sum of given two numbers is 310



How to return a function pointer without typedef in c?
Just return the address of a function(function name or value of function pointer) as return value.  Below program explains how to return function pointer.  We haven't used any type definitions for function pointer in the below program.  But, usage of type definition in function pointer simplifies the codes and makes us easy to understand.


  #include <stdio.h>

  /* sum of two numbers */
  int add(int a, int b) {
        return (a + b);
  }

  /* difference of two numbers */
  int sub(int a, int b) {
        return (a - b);
  }

  /* product of two numbers */
  int multiply(int a, int b) {
        return (a * b);
  }

  /* division of two numbers */
  int divide(int a, int b) {
        return (a / b);
  }

  /*
   * choice() is a function that takes an integer argument(ch)
   * and returns a function pointer.  The returned 
   * function pointer takes two integer arguments and returns
   * an integer value
   */
  int (*choice(int ch))(int , int) {
        switch (ch) {
                case 1:
                        return (add);
                case 2:
                        return (sub);
                case 3:
                        return (multiply);
                case 4:
                        return (divide);
        }
  }

  int main() {
        int num1, num2, ch, res;
        int (*fptr)(int, int); // function pointer declaration

        /* get the inputs from the user */
        printf("Enter your first input: ");
        scanf("%d", &num1);
        printf("Enter your second input: ");
        scanf("%d", &num2);

        /* get the choice from the user */
        printf("1. Add\t2. Sub\n");
        printf("3. Multiply\t4.Divide\n");
        printf("Enter your choice:");
        scanf("%d", &ch);

        /* choice is a function returns function pointer */
        fptr = choice(ch);

        /*
         * calls add/sub/multiply/divide based on
         * the value of function pointer
         */
        res = (*fptr)(num1, num2);
        printf("Result is %d\n", res);
        return 0;
  }



How to return a function pointer with typedef?
Below program explains how to return a function pointer using type definitions.


  #include <stdio.h>
  /*
   * type definition for function pointer that takes
   * two integer arguments and returns an integer
   */
  typedef int (*fptr)(int, int);

  /* returns sum of two numbers */
  int add(int a, int b) {
        return (a + b);
  }

  /*
   * function returning function pointer
   * fptr - is the typedef for function pointer
   */
  fptr wrapper() {
        return (add);
  }

  int main() {
        int num1 = 10, num2 = 20, res;
        fptr func_ptr; // function pointer declaration

        /* wrapper() returns address of add() api */
        func_ptr = wrapper();
        /* calling add() using function pointer */
        res = (*func_ptr)(num1, num2);

        /* printing the result */
        printf("Sum of %d and %d is %d\n", num1, num2, res);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Sum of 10 and 20 is 30



How to declare function pointers as structure member?
Function pointers can be declared as structure member like other normal variables.  Below code snippet gives clear idea on how to declare function pointer as structure member.

  struct mathOps {
       int val1, val2;
       int (*add) (int, int);  // function pointer takes two int args and returns an integer
       int (*sub) (int, int);  
       void (*print) (char *); // function pointer takes a character pointer as argument
  };


How to invoke function pointers defined in a structure?
Below program explains how to invoke function pointer defined inside a structure.


  #include <stdio.h>
  #include <stdlib.h>
  /* structures with function pointer as its member */
  struct msg {
        void (*printMsg)(char *);
  };

  struct mathOp {
        int (*add)(int, int);
  };

  /* prints the given message */
  void printMessage(char *str) {
        printf("%s\n", str);
        return;
  }

  /* adds the given two numbers */
  int addTwoNum(int a, int b) {
        return (a + b);
  }

  int main() {
        char str[128];
        struct msg m1; // structure object
        struct mathOp *op;  // pointer to a structure
        int num1 = 10, num2 = 20, res;

        /* dynamic memory allocation */
        op = (struct mathOp *) malloc(sizeof(struct mathOp));

        /* function pointer initialization */
        m1.printMsg = printMessage;
        op->add = addTwoNum;

        /* calling addTwoNum() using function pointer */
        res = op->add(num1, num2); // -> operator is used since op is ptr

        /* storing output in a string */
        sprintf(str, "Sum of %d and %d is %d", num1, num2, res);

        /* calling printMessage() using function pointer */
        m1.printMsg(str);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/cpgms/pointers$ ./a.out
  Sum of 10 and 20 is 30




How to cast void pointer to function pointer in c?
Below code snippet explains how to typecast void pointer to function pointer.
  int add(int, int); // function
  int (*func)(int, int);  // function pointer
  void *ptr;  // void pointer
  ptr = add  // assigning address of a function to void poiter
  func = (int (*)(int, int)) ptr; // type casting void pointer to function pointer
  (*func)(a, b);  // invoking add() using function pointer

Finally, we have done typecasting void pointer to function pointer.


  #include <stdio.h>
  /* adds given two numbers */
  void add(int a, int b) {
        printf("Sum of %d and %d is %d\n", a, b, (a + b));
  }

  int main() {
        void *ptr;  // void pointer
        void (*fptr)(int, int);  // function pointer

        ptr = add;  // assigning value to void pointer

        /* typecasting void pointer to function pointer */
        fptr = (void (*)(int, int))ptr;

        /* calling add() using function pointer */
        (*fptr)(100, 300);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Sum of 100 and 300 is 400


How to declare array of function pointers in c?
int (*func_ptr[])();
Here, func_ptr is an array of pointer to a function returning integer.

Typedef is usually used to simplify complex pointer declarations.  The above can also be written as follows.
typedef int (*func_ptr) ()
func_ptr fptr[];
Here, fptr is an array of pointer to function returning integer.

constant pointer, pointer to a constant and constant pointer to a constant

const pointer, pointer to a constant and const pointer to a constant:
If a pointer declaration contains const type qualifier, then it would be either const pointer or pointer to constant or constant pointer to a constant.

const pointer:
What is constant pointer?
A constant pointer is a pointer whose value(address to which the pointer points to) cannot be changed after initialization.  But, we can change the value(pointee) to which the pointer points to.

How to declare constant pointer?
The qualifier const needs to be located in between the asterisk and pointer name.

     int      * const ptr;
    <type> * const <pointer-name>


Below is an example program for constant pointers.

  /* constant pointer */
  #include <stdio.h>
  int main() {
        int num1 = 10, num2 = 20;
        int * const ptr = &num1;
        printf("ptr: 0x%x\t *ptr: %d\n", (int)ptr, *ptr);
        /* trying to change the value of const pointer */
        ptr = &num2;
        printf("ptr: 0x%x\t *ptr: %d\n", (int)ptr, *ptr);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ gcc -Wall constptr.c 
  constptr.c: In function ‘main’:
  constptr.c:7: error: assignment of read-only variable ‘ptr’


We are trying to alter the value of the pointer after initialization.  That's the reason for the above error message.  Basically, we cannot change the value of the const pointer after initialization.




  /* constant pointer */
  #include <stdio.h>
  int main() {
        int num1 = 10;
        /* const pointer initialization */
        int * const ptr = &num1;
        printf("ptr: 0x%x\t *ptr: %d\n", (int)ptr, *ptr);
        /* changing the value at the address in pointer  */
        *ptr = 20;
        printf("ptr: 0x%x\t *ptr: %d\n", (int)ptr, *ptr);
        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ gcc -Wall constptr.c 
  jp@jp-VirtualBox:~/$ ./a.out
  ptr: 0xbfb0795c *ptr: 10
  ptr: 0xbfb0795c *ptr: 20


The above program explains that we can alter the value to which a const pointer points to(in the case of constant pointer).



Pointer to constant:
What is pointer to constant?
Pointer to a constant is nothing but the value to which a pointer refers to cannot be changed after initialization.

How to declare pointer to constant?
The qualifier const needs to be located before the type of the pointer variable.

      const   int      * ptr;
      const <type>  * <pointer-name>


Below is an example program for pointer to constant.

  #include <stdio.h>
  int main() {
        int num = 10;
        const int * ptr = &num;
        /* changing the value at the address in pointer */
        *ptr = 20;
        printf("ptr: 0x%x\t*ptr: %d\n", (int)ptr, *ptr);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ gcc ptr2const.c 
  ptr2const.c: In function ‘main’:
  ptr2const:6: error: assignment of read-only location ‘*ptr’


We are trying to alter the value(constant) to which the pointer points to.  That's the reason for the above error message.  Basically, the value to which the pointer points to cannot be altered in the case of pointer to a constant.


  #include <stdio.h>
  int main() {
        int num1 = 10, num2 = 20;
        const int * ptr = &num1;
        printf("ptr: 0x%x\t*ptr: %d\n", (int)ptr, *ptr);
        /* changing the pointer value */
        ptr = &num2;
        printf("ptr: 0x%x\t*ptr: %d\n", (int)ptr, *ptr);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ gcc -Wall ptr2const.c
  jp@jp-VirtualBox:~/$ ./a.out
  ptr: 0xbfa1103c *ptr: 10
  ptr: 0xbfa11038 *ptr: 20


The above program explains that the pointer value can be altered in the case of pointer to a constant.



constant pointer to a constant:
What is constant pointer to a constant?
If the value of the pointer and pointee(the value to which pointer points to) cannot be altered after initialization, then it called constant pointer to a constant.

How to declare constant pointer to a constant?
The const qualifier needs to be located at two places as shown below.

     const  int      *  const    ptr;
     const <type> *  const  <pointer-name>;


Below is an example program for constant pointer to a constant.

  #include <stdio.h>
  int main() {
        int num1 = 10, num2 = 20;
        const int * const ptr = &num1;
        /* changing the pointee value */
        *ptr = 30;
        /* changing the pointer value */
        ptr = &num2;
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/cpgms/pointers$ gcc -Wall cptr2const.c 
  cptr2const.c: In function ‘main’:
  cptr2const.c:6: error: assignment of read-only location ‘*ptr’
  cptr2const.c:8: error: assignment of read-only variable ‘ptr’


We have tried to modify the value of pointer and pointee.  That's the reason for the above error message.  We cannot alter neither pointer nor pointee in the case of constant pointer to a constant.

Pointer to an array vs Array of pointers

Difference between pointer to an array and array of pointers in c?

Pointer to an array:
Pointer to an array is also called as array pointer.

How to declare pointer to an array?
int (* ptr)[3] = NULL; /* pointer to an array of three integers */

The above declaration is the pointer to an array of 3 integers.  We need to use parenthesis to declare pointer to an array.  If we are not using parenthesis, then it would become array of pointers.  Here, the base type of pointer ptr is 3-integer array.

How to assign value to array pointer(pointer to an array)?
Consider the below example,
int arr[3][3];
ptr = arr;
"arr" is a two dimensional array with three rows and three columns.  We have assigned the address of arr[0][0](arr is equivalent to &arr[0][0]) to pointer ptr. So, pointer ptr points to the first row of the matrix "arr".  If ptr is incremented(ptr++), then it will point to the next three elements in the array "arr".  If ptr is decremented(ptr--), then it will point to the previous three elements in the array "arr".


  #include <stdio.h>
  int main() {
        int arr[3][3]; /* 3 X 3 integer array */
        int (*ptr)[3]; /* pointer to an array */

        /* assiging value to pointer */
        ptr = arr;

        /* printing addresses and values */
        printf("value of arr: 0x%x\n", arr);
        printf("value of ptr: 0x%x\n", ptr);
        printf("&arr[0][0]  : 0x%x\n", &arr[0][0]);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  value of arr: 0xbfd1b6e8
  value of ptr: 0xbfd1b6e8
  &arr[0][0]  : 0xbfd1b6e8



How to assign values to array elements using array pointers(pointer to an array)?
Consider the following examples,
     ptr[0][0] = 10;
     (*ptr)[0] = 10;
     **ptr     = 10;
All the above statements assigns value to arr[0][0](first element of the array).

     ptr[i][j]             = 20;
     (*(ptr + i))[j]     = 20;
     *(*(ptr + i) + j) = 20;
All the above statements assigns value to arr[i][j] (jth element in the ith row of the array).

How to access array elements using array pointers (pointer to an array)?
arr[0][0] is equivalent to ptr[0][0]
arr[0][0] is equivalent to (*ptr)[0]
arr[0][0] is equivalent to **ptr

arr[i][j] is equivalent to ptr[i][j]
arr[i][j] is equivalent to (*(ptr + i))[j]
arr[i][j] is equivalent to *(*(ptr + i) + j)

The below program explains how to assign values to array elements and access values from array elements using array pointers.

  #include <stdio.h>
  int main() {
        int arr[3][3]; /* 3 X 3 integer array */
        int (*ptr)[3]; /* pointer to an array */
        int i = 0, j, k = 1;

        /* assiging value to pointer */
        ptr = arr;

        /* assinging values to array elements */
        for (j = 0; j < 3; j++) {
                ptr[i][j] = k++;
        }

        i++;

        for (j = 0; j < 3; j++) {
                (*(ptr + i))[j] = k++;
        }

        i++;

        for (j = 0; j < 3; j++) {
                *(*(ptr + i) + j) = k++;
        }

        /* accessing values from array */
        printf("Values in the array arr[i][j]:\n");
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        printf("%d ", arr[i][j]);
                }
        }

        /* accessing values of the array elements using array pointers */
        printf("\nAccessing values using pointers (*(ptr + i))[j]:\n");
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        printf("%d ", (*(ptr + i))[j]);
                }
        }

        printf("\nAccessing values using pointers *(*(ptr + i) + j):\n");
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        printf("%d ", *(*(ptr + i) + j));
                }
        }

        printf("\n");

        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Values in the array arr[i][j]:
  1 2 3 4 5 6 7 8 9 
  Accessing values using pointers (*(ptr + i))[j]:
  1 2 3 4 5 6 7 8 9 
  Accessing values using pointers *(*(ptr + i) + j):
  1 2 3 4 5 6 7 8 9 



How to pass array pointers(pointer to an array) as arguments to function?
If we want to pass multidimensional array/array pointer to a function, then we need to declare the function parameter as a pointer to an array.

void arrayPointer(int (*pointer)[3]);

Here, the parameter is the pointer to an array of three integers.

Dynamic memory allocation for array pointers(pointer to an array)?
         int (*ptr)[3];
         ptr = (int (*)[3]) malloc(9 * sizeof(int));

The above statement allocates memory to hold a 3 X 3 array.  Of-course, ptr is the pointer to an array of integers.

The below program explains how to pass array pointers as parameters to function and also it explains about dynamic memory allocation for array pointers.


  #include <stdio.h>
  #include <stdlib.h>

  /* function with array pointers as arguments */
  void arrayPointers(int (*arr)[3], int (*ptr)[3]) {
        int i, j, k = 1;

        /* updating values for the given array pointers */
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        ptr[i][j] = arr[i][j] = k++;
                }
        }
        return;
  }

  int main() {
        int i, j, arr[3][3], (*ptr)[3];

        /* dynamic memory allocation for array pointer */
        ptr = (int (*)[3]) malloc(sizeof(int) * 9);

        arrayPointers(arr, ptr);

        /* printing values of the array(arr) */
        printf("Values in array(arr):\n");
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        printf("%d ", arr[i][j]);
                }
        }
        printf("\n");

        /* printing the values of the array(ptr) */
        printf("Values in array(ptr):\n");
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        printf("%d ", ptr[i][j]);
                }
        }
        printf("\n");
        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Values in array(arr):
  1 2 3 4 5 6 7 8 9 
  Values in array(ptr):
  1 2 3 4 5 6 7 8 9 



Array of pointers:
It is also called as pointer arrays.

How to declare array of pointers?
int *ptr[3];
Above is the declaration for an array of three integer pointers.

How to assign values to pointer arrays(array of pointers)?
int a[10], b[10], c[10];
ptr[0] = &a[0][0];
ptr[1] = &b[0][0];
ptr[2] = &c[0][0];

We have assigned the address of first elements of the arrays a, b and c to the pointers ptr[0], ptr[1] and ptr[2] correspondingly.  The above statements can also be written as below.

ptr[0] = a;
ptr[1] = b;
ptr[2] = c;

Because, 
a is equivalent to &a[0][0]
b is equivalent to &b[0][0]
c is equivalent to &c[0][0]


How to assign values to array elements using pointer arrays?
ptr[0][0] = 20;  /* assigns value to the first element of the array a */
*(ptr[1] + 2) = 20; /* assigns value to the second element of the array b */
*(*(ptr + 2) + 2) = 20; /* assigns value to the third element of the array c */

How to access array elements using pointer arrays?
a[1] is equivalent to ptr[0][1]
b[1] is equivalent to ptr[1][1]
c[1]  is equivalent to ptr[2][1]

The above can also be written as follows
a[1] is equivalent to *(ptr[0] + 1)
b[1] is equivalent to *(ptr[1] + 1)
c[1] is equivalent to *(ptr[2] + 1)

The above can also be written as follows
a[1] is equivalent to *(*ptr + 1)
b[1] is equivalent to *(*(ptr + 1) + 1)
c[1] is equivalent to *(*(ptr + 2) + 1)


  #include <stdio.h>
  int main() {
        /* array declaration + assinging values to array elements */
        int a[3] = {1, 2, 3}, b[3] = {4, 5, 6};
        int i, c[3], *ptr[3]; /* ptr is pointer to an array */

        /* assigning values to pointer array */
        ptr[0] = a;
        ptr[1] = &b[0];
        ptr[2] = c;

        /* assinging values to array elements using pointer array */
        ptr[2][0] = 7;
        *(ptr[2] + 1) = 8;
        *(*(ptr + 2) + 2) = 9;

        /* accessing array elements using pointer array */
        printf("Accessing array values using pointer array:\n");
        for (i = 0; i < 3; i++) {
                printf("%d ", ptr[0][i]);
        }

        for (i = 0; i < 3; i++) {
                printf("%d ", *(ptr[1] + i));
        }

        for (i = 0; i < 3; i++) {
                printf("%d ", *(*(ptr + 2) + i));
        }

        printf("\n");
        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Accessing array values using pointer array:
  1 2 3 4 5 6 7 8 9 



How to pass pointer array(array of pointers) as arguments to function?
If we want to pass an array of pointers to a function, then we need to declare the function parameter as an array of pointers without any subscript.

void pointerArray(int *pointer[ ]);

Here, the parameter is an array of pointers.

Dynamic memory allocation for pointer arrays(array of pointers)?
         int *ptr[3];
         ptr[0] = (int *)malloc(sizeof(int) * 4);
         ptr[1] = (int *)malloc(sizeof(int) * 4);
         ptr[2] = (int *)malloc(sizeof(int) * 4);

The above statements does dynamic memory allocation.  But, each pointer(ptr[0], ptr[1], ptr[2]) points to different memory blocks.  Here, the memory block pointed by pointer ptr is not contiguous.


  #include <stdio.h>
  #include <stdlib.h>

  /* function with array of pointers as arguments */
  void arrayOfPointers(int *ptr[]) {
        int i, j, k = 1;

        /* updating ptr array with new values */
        for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                        ptr[i][j] = k++;
                }
        }
  }

  int main() {
        int i, *ptr[3];

        /* dynamic memory allocation for array of pointers */
        for (i = 0; i < 3; i++) {
                ptr[i] = (int *) malloc(sizeof(int) * 3);
        }

        arrayOfPointers(ptr);

        /* printing the addresses and values of each element in the array(ptr) */
        printf("values & address(ptr[0]):\n");
        for (i = 0; i < 3; i++) {
                printf("    %d    0x%x\n", ptr[0][i], &ptr[0][i]);
        }

        printf("values & address(ptr[1]):\n");
        for (i = 0; i < 3; i++) {
                printf("    %d    0x%x\n", ptr[1][i], &ptr[1][i]);
        }

        printf("values & address(ptr[2]):\n");
        for (i = 0; i < 3; i++) {
                printf("    %d    0x%x\n", ptr[2][i], &ptr[2][i]);
        }

        return 0;
  }




  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  values & address(ptr[0]):
    1    0x93d0008
    2    0x93d000c
    3    0x93d0010
  values & address(ptr[1]):
    4    0x93d0018
    5    0x93d001c
    6    0x93d0020
  values & address(ptr[2]):
    7    0x93d0028
    8    0x93d002c
    9    0x93d0030