Pointer to a Double Dimension Array of Structures ================================================== 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 Double dimension array ` .. _ptr_to_array_struct_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 struct ABC { int a; int b; }; struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; struct ABC (*ptr)[2][3]; ptr = &a; .. _ptr_to_array_struct_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 struct ABC { int a; int b; }; struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; * Step 2 : Define a pointer to an array .. code-block:: c struct ABC (*ptr)[2][3]; * 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 struct ABC { int a; int b; }; int main(void) { struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; struct ABC (*ptr)[2][3]; 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 = 7fff70176280 After Increment : ptr = 7fff701762b0 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Observe that difference is 48 ! * Size of two dimensional array is 48 Bytes * Hence incrementing ``ptr`` will increment by 48 Bytes .. _ptr_to_array_struct_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 struct ABC { int a; int b; }; struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; * Step 2 : Define a pointer to an array .. code-block:: c struct ABC (*ptr)[2][3]; * 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( struct ABC (*p)[2][3] ) { } * Step 6 : Print individual structures inside ``fun`` .. code-block:: c void fun( struct ABC (*p)[2][3] ) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(*p)[%d][%d].a = %d ", i, j, (*p)[i][j].a); printf("(*p)[%d][%d].b = %d ", i, j, (*p)[i][j].b); printf("\n"); } 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 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] * 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 an structure then ``(*p)[i][j]`` is also an structure .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Another way to understand ! * ``int (*p)[2][4]`` is the declaration of pointer ``p`` * ``(*p)[ ][ ]`` is dereferenced to maximum level. Hence is an structure * See full program below .. code-block:: c #include struct ABC { int a; int b; }; void fun( struct ABC (*p)[2][3] ) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(*p)[%d][%d].a = %d ", i, j, (*p)[i][j].a); printf("(*p)[%d][%d].b = %d ", i, j, (*p)[i][j].b); printf("\n"); } printf("\n"); } } int main(void) { struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; struct ABC (*ptr)[2][3]; ptr = &a; fun(ptr); return 0; } * Output is as below .. code-block:: c (*p)[0][0].a = 1 (*p)[0][0].b = 2 (*p)[0][1].a = 3 (*p)[0][1].b = 4 (*p)[0][2].a = 5 (*p)[0][2].b = 6 (*p)[1][0].a = 10 (*p)[1][0].b = 20 (*p)[1][1].a = 30 (*p)[1][1].b = 40 (*p)[1][2].a = 50 (*p)[1][2].b = 60 .. _ptr_to_array_struct_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 struct ABC { int a; int b; }; struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; * Step 2 : Define a pointer to an array .. code-block:: c struct ABC (*ptr)[2][3]; * 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 structures .. code-block:: c void fun(struct ABC (**p)[2][3]) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(**p)[%d][%d].a = %d ", i, j, (**p)[i][j].a); printf("(**p)[%d][%d].b = %d ", i, j, (**p)[i][j].b); printf("\n"); } 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] * 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 structure then ``(**p)[i][j]`` is also a structure * See full program below .. code-block:: c #include struct ABC { int a; int b; }; void fun(struct ABC (**p)[2][3]) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(**p)[%d][%d].a = %d ", i, j, (**p)[i][j].a); printf("(**p)[%d][%d].b = %d ", i, j, (**p)[i][j].b); printf("\n"); } printf("\n"); } } int main(void) { struct ABC a[2][3] = { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, {.a = 5, .b = 6}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, {.a = 50, .b = 60}, }, }; struct ABC (*ptr)[2][3]; ptr = &a; fun(&ptr); return 0; } * Output is as below .. code-block:: c (**p)[0][0].a = 1 (**p)[0][0].b = 2 (**p)[0][1].a = 3 (**p)[0][1].b = 4 (**p)[0][2].a = 5 (**p)[0][2].b = 6 (**p)[1][0].a = 10 (**p)[1][0].b = 20 (**p)[1][1].a = 30 (**p)[1][1].b = 40 (**p)[1][2].a = 50 (**p)[1][2].b = 60 .. _ptr_to_array_struct_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 structures .. code-block:: c struct ABC { int a; int b; }; struct ABC a[2][2][2] = { { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, }, }, { { {.a = 100, .b = 200}, {.a = 300, .b = 400}, }, { {.a = 1000, .b = 2000}, {.a = 3000, .b = 4000}, }, } }; * Step 2 : Define a pointer to an array of double dimension .. code-block:: c struct ABC (*ptr)[2][2]; * 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 individual structures .. code-block:: c for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { printf("(*ptr)[%d][%d][%d].a = %d ", i, j, k, ptr[i][j][k].a); printf("(*ptr)[%d][%d][%d].b = %d ", i, j, k, ptr[i][j][k].b); printf("\n"); } } 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 .. 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] * Rule 7 : ``a[0][0]`` is equal to ``&a[0][0][0]`` .. code-block:: c ptr[0][0] = &a[0][0][0] * Rule 8 : Move & from RHS to LHS. This becomes * on LHS .. code-block:: c *ptr[0][0] = a[0][0][0] * Rule 9 : ``*`` and ``[ ]`` can be used interchangeably .. code-block:: c ptr[0][0][0] = a[0][0][0] * Rule 10 : Extending Rule 9 .. code-block:: c ptr[i][j][k] = a[i][j][k] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence we proved, if ``a[i][j][k]`` is a structure then ``p[i][j][k]`` is also also a structure * See full program below .. code-block:: c #include struct ABC { int a; int b; }; int main(void) { struct ABC a[2][2][2] = { { { {.a = 1, .b = 2}, {.a = 3, .b = 4}, }, { {.a = 10, .b = 20}, {.a = 30, .b = 40}, }, }, { { {.a = 100, .b = 200}, {.a = 300, .b = 400}, }, { {.a = 1000, .b = 2000}, {.a = 3000, .b = 4000}, }, } }; struct ABC (*ptr)[2][2]; ptr = &a[0]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { printf("(*ptr)[%d][%d][%d].a = %d ", i, j, k, ptr[i][j][k].a); printf("(*ptr)[%d][%d][%d].b = %d ", i, j, k, ptr[i][j][k].b); printf("\n"); } } printf("\n"); } return 0; } * Output is as below .. code-block:: c (*ptr)[0][0][0].a = 1 (*ptr)[0][0][0].b = 2 (*ptr)[0][0][1].a = 3 (*ptr)[0][0][1].b = 4 (*ptr)[0][1][0].a = 10 (*ptr)[0][1][0].b = 20 (*ptr)[0][1][1].a = 30 (*ptr)[0][1][1].b = 40 (*ptr)[1][0][0].a = 100 (*ptr)[1][0][0].b = 200 (*ptr)[1][0][1].a = 300 (*ptr)[1][0][1].b = 400 (*ptr)[1][1][0].a = 1000 (*ptr)[1][1][0].b = 2000 (*ptr)[1][1][1].a = 3000 (*ptr)[1][1][1].b = 4000 .. 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`