Pointer to a Double Dimension Array of Characters ================================================== In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to define and use Pointer to Double Dimension Arrays ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Pointer to an Array * :ref:`Syntax of Pointer to an array ` * :ref:`Pointer to an array increments by size of the array ` * :ref:`Pointer to an array : Passed as function arguement : Call by Value ` * :ref:`Pointer to an array : Passed as function arguement : Call by Reference ` * :ref:`Pointer to an array : Pointing to Double dimension array inside a Triple dimension array ` .. _ptr_to_array_char_dp_ex_1: .. tab-set:: .. tab-item:: Syntax of Pointer to an array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow type ( \*ptr ) [ row_size ] [ col_size ]; An example is as below .. code-block:: c char a[2][4] = { "Yes", "No" }; char (*ptr)[2][4]; ptr = &a; .. _ptr_to_array_char_dp_ex_2: .. tab-set:: .. tab-item:: Pointer to an array increments by size of the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Pointer to an Array when incremented, increments by size of the array to which it is pointing to ! .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Pointer to an Array when decremented, decrements by size of the array to which it is pointing to ! .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us see how it is done. See below * Step 1 : Define a double dimension array .. code-block:: c char a[2][4] = { "Yes", "No" }; * Step 2 : Define a pointer to an array .. code-block:: c char (*ptr)[2][4]; * Step 3 : Let pointer to an array, point to double dimension array .. code-block:: c ptr = &a; * Step 4 : Check pointer arithmetic .. code-block:: c 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 .. code-block:: c #include int main(void) { char a[2][4] = { "Yes", "No" }; char (*ptr)[2][4]; 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 .. code-block:: c Before Increment : ptr = 7ffd4a34b670 After Increment : ptr = 7ffd4a34b678 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Observe that difference is 8 ! * Size of two dimensional array is 8 Bytes * Hence incrementing ``ptr`` will increment by 8 Bytes .. _ptr_to_array_char_dp_ex_3: .. tab-set:: .. tab-item:: Pointer to an array : Passed as function arguement : Call by Value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow When Pointer to an Array is passed as argument, Prototype of function should match the type properly ! .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us see how it is done. See below * Step 1 : Define a double dimension array .. code-block:: c char a[2][4] = { "Yes", "No" }; * Step 2 : Define a pointer to an array .. code-block:: c char (*ptr)[2][4]; * Step 3 : Let pointer to an array, point to double dimension array .. code-block:: c ptr = &a; * Step 4 : Pass ``ptr`` as argument to function ``fun`` .. code-block:: c fun(ptr); * Step 5 : Define function ``fun`` .. code-block:: c void fun( char (*p)[2][4] ) { } * Step 6 : Print individual strings inside ``fun`` .. code-block:: c void fun( char (*p)[2][4] ) { //print strings printf("Print strings using %%s\n"); for (int i = 0; i < 2; i++) { printf("%s\n", (*p)[i]); } } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow This is easy to understand ! Let us derive the rules * Rule 1 : Base Rule inside ``main`` .. code-block:: c ptr = &a * Rule 2 : Base Rule inside ``fun`` .. code-block:: c p = ptr * Rule 3 : From Rule 1 and Rule 2 .. code-block:: c p = &a * Rule 4 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c *p = a; * Rule 5 : ``a`` is equal to ``&a[0]`` .. code-block:: c *p = &a[0] * Rule 6 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c **p = a[0] * Rule 7 : * and [ ] can be used interchangeably .. code-block:: c (*p)[0] = a[0] * Rule 8 : Extending Rule 7 .. code-block:: c (*p)[i] = a[i] * Note that ``a[i]`` is a string (Array of characters) * Hence ``(*p)[i]`` is also a string (Array of characters from Rule 8) .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Another way to understand ! * ``char (*p)[2][4]`` is the declaration of pointer ``p`` * ``(*p)[ ][ ]`` is dereferenced to maximum level. Hence is a character * ``(*p)[ ]`` is dereferenced to (N - 1)th level. Hence is an array of characters * Step 7 : Print individual characters inside ``fun`` .. code-block:: c void fun( char (*p)[2][4] ) { //print Individual characters printf("Print characters using %%c\n"); for (int i = 0; i < 2; i++) { for (int j = 0; j < 4; j++) { printf("%c", (*p)[i][j]); } printf("\n"); } } * See full program below .. code-block:: c #include void fun( char (*p)[2][4] ) { //print strings printf("Print strings using %%s\n"); for (int i = 0; i < 2; i++) { printf("%s\n", (*p)[i]); } printf("\n"); //print Individual characters printf("Print characters using %%c\n"); for (int i = 0; i < 2; i++) { for (int j = 0; j < 4; j++) { printf("%c", (*p)[i][j]); } printf("\n"); } } int main(void) { char a[2][4] = { "Yes", "No" }; char (*ptr)[2][4]; ptr = &a; fun(ptr); return 0; } * Output is as below .. code-block:: c Print strings using %s Yes No Print characters using %c Yes No .. _ptr_to_array_char_dp_ex_8: .. tab-set:: .. tab-item:: Pointer to an array : Passed as function arguement : Call by Reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow When Pointer to an Array is passed as argument by call by reference, Prototype of function should match the type properly ! .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us see how it is done. See below * Step 1 : Define a Double dimension array .. code-block:: c char a[3][10] = { "Laptop", "Keyboard", "Mouse" }; * Step 2 : Define a pointer to an array .. code-block:: c char (*ptr)[3][10]; * Step 3 : Let pointer to an array, point to double dimension array .. code-block:: c ptr = &a; * Step 4 : Pass ``ptr`` as argument to function ``fun``. Call by reference .. code-block:: c fun(&ptr); * Step 5 : Define function ``fun`` and print individual strings .. code-block:: c void fun(char (**p)[3][10]) { for (int i = 0; i < 3; i++) { printf("%s\n", (**p)[i]); } } * Step 6 : Define function ``fun`` and print individual characters .. code-block:: c void fun(char (**p)[3][10]) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 10; j++) { printf("%c", (**p)[i][j]); } printf("\n"); } } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow This is easy to understand ! Let us derive the rules * Rule 1 : Base rule in ``main`` .. code-block:: c ptr = &a; * Rule 2 : Base rule in ``fun`` .. code-block:: c p = &ptr * Rule 2 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c *p = ptr * Rule 3 : Replace ``ptr`` referring to Rule 1 .. code-block:: c *p = &a * Rule 4 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c **p = a * Rule 5 : ``*`` and ``[ ]`` can be used interchangeably .. code-block:: c (*p)[0] = a * Rule 6 : ``a`` is equal to ``&a[0]`` .. code-block:: c (*p)[0] = &a[0] * Rule 7 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c (**p)[0] = a[0] * Rule 8 : Extending Rule 7 .. code-block:: c (**p)[i] = a[i] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence we proved if ``a[i]`` is a string then ``(**p)[i]`` is also a string .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * Rule 9 : ``a[0]`` is equal to ``&a[0][0]`` .. code-block:: c (**p)[0] = &a[0][0] * Rule 10 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c (***p)[0] = a[0][0] * Rule 11 : * and [ ] can be used interchangeably .. code-block:: c (**p)[0][0] = a[0][0] * Rule 12 : Extending Rule 11 .. code-block:: c (**p)[i][j] = a[i][j] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence we proved if ``a[i][j]`` is a character then ``(**p)[i][j]`` is also a character * See full program below .. code-block:: c #include void fun(char (**p)[3][10]) { // Print strings printf("Print string using %%s\n"); for (int i = 0; i < 3; i++) { printf("%s\n", (**p)[i]); } printf("\n"); // Print individual characters printf("Print characters using %%c\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 10; j++) { printf("%c", (**p)[i][j]); } printf("\n"); } } int main(void) { char a[3][10] = { "Laptop", "Keyboard", "Mouse" }; char (*ptr)[3][10]; ptr = &a; fun(&ptr); return 0; } * Output is as below .. code-block:: c Print string using %s Laptop Keyboard Mouse Print characters using %c Laptop Keyboard Mouse .. _ptr_to_array_char_dp_ex_6: .. tab-set:: .. tab-item:: Pointer to an array : Pointing to Double dimension array inside a Triple dimension array * Step 1 : Define a triple dimension array of characters .. code-block:: c char a[3][4][5] = { { "Lap0", "Key0", "Mou0", "tou0" }, { "Lap1", "Key1", "Mou1", "tou1" }, { "Lap2", "Key2", "Mou2", "tou2" }, }; * Step 2 : Define a pointer to an array of double dimension .. code-block:: c char (*ptr)[4][5]; * Step 3 : Let the pointer to point to Double dimension array inside a Double dimension array .. code-block:: c ptr = &a[0]; * Step 4 : Print the strings using ``%s`` : Method 1 .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("ptr[%d][%d] = %s\n", i, j, ptr[i][j]); } } * Step 5 : Print the strings using ``%s`` : Method 2 .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("(*ptr)[%d] = %s\n", j, (*ptr)[j]); } ptr++; } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow This is easy to understand ! Let us derive the rules * Rule 1 : Base rule .. code-block:: c ptr = &a[0]; * Rule 2 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c *ptr = a[0] * Rule 3 : ``a[0]`` is equal to ``&a[0][0]`` .. code-block:: c *ptr = &a[0][0] * Rule 4 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c **ptr = a[0][0] * Rule 5 : ``*`` and ``[ ]`` can be used interchangeably .. code-block:: c ptr[0][0] = a[0][0] * Rule 6 : Extending Rule 3 .. code-block:: c ptr[i][j] = a[i][j] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence we proved, if ``a[i][j]`` is a string then ``p[i][j]`` is also a string * See full program below .. code-block:: c #include int main(void) { char a[3][4][5] = { { "Lap0", "Key0", "Mou0", "tou0" }, { "Lap1", "Key1", "Mou1", "tou1" }, { "Lap2", "Key2", "Mou2", "tou2" }, }; char (*ptr)[4][5]; ptr = &a[0]; //Method 1 : print strings for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("ptr[%d][%d] = %s\n", i, j, ptr[i][j]); } } printf("\n"); //Method 2 : print strings for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("(*ptr)[%d] = %s\n", j, (*ptr)[j]); } ptr++; } return 0; } * Output is as below .. code-block:: c ptr[0][0] = Lap0 ptr[0][1] = Key0 ptr[0][2] = Mou0 ptr[0][3] = tou0 ptr[1][0] = Lap1 ptr[1][1] = Key1 ptr[1][2] = Mou1 ptr[1][3] = tou1 ptr[2][0] = Lap2 ptr[2][1] = Key2 ptr[2][2] = Mou2 ptr[2][3] = tou2 (*ptr)[0] = Lap0 (*ptr)[1] = Key0 (*ptr)[2] = Mou0 (*ptr)[3] = tou0 (*ptr)[0] = Lap1 (*ptr)[1] = Key1 (*ptr)[2] = Mou1 (*ptr)[3] = tou1 (*ptr)[0] = Lap2 (*ptr)[1] = Key2 (*ptr)[2] = Mou2 (*ptr)[3] = tou2 .. card:: See Also * Current Module * :doc:`../ptr_to_array` * Previous Module * :doc:`../../array_of_ptr/array_of_ptr` * Next Module * :doc:`../../function_ptr/function_ptr` * Other Modules * :doc:`../../variable_and_ptr/variable_and_ptr` * :doc:`../../array_n_ptrs/array_n_ptrs` * :doc:`../../malloc_ptr/malloc_ptr` * :doc:`../../typecasting_n_ptr/typecasting_n_ptr` * :doc:`../../funcs_n_ptrs/funcs_n_ptrs` * :doc:`../../memcpy_ptr/memcpy_ptr` * :doc:`../../const_ptr/const_ptr` * :doc:`../../void_ptr/void_ptr` * :doc:`../../pre_incr_ptr/pre_incr_ptr` * :doc:`../../post_incr_ptr/post_incr_ptr` * :doc:`../../pre_decr_ptr/pre_decr_ptr` * :doc:`../../post_decr_ptr/post_decr_ptr`