Functions and Structure Double Pointer ================================================== In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow What are the calling conventions of structure double dimension array ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Call by Value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Call by Reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Revisit Basics : :doc:`../../basic_ptr/basic_struct_ptr/struct_dp` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Structure Double Pointer : Syntax ` * :ref:`Structure Double Pointer : FAQs ` * :ref:`Structure Double Pointer : fun(expression) ` * :ref:`Rules for Call By Value ` * :ref:`Example : Call by Value : Pass Structure : dp[1][1] ` * :ref:`Example : Call by Value : Pass Structure : **dp ` * :ref:`Rules for Call By Reference ` * :ref:`Example : Call by Reference : &dp[1][1] ` * :ref:`Example : Call by Reference : dp[1] ` * :ref:`Examples of Call by Value ` * :ref:`Example 1 : Call by Value : Pass Structure : dp[0][0], dp[1][0], dp[1][1] ` * :ref:`Example 2 : Call by Value : Pass Structure : **dp, *(*(dp + 1) + 0), *(*(dp + 1) + 1) ` * :ref:`Examples of Call by Reference ` * :ref:`Example 3 : Call by Reference : Pass Single dimension arrays which are part of a double dimension array to a function ` * :ref:`Example 4 : Call by Reference : Pass Address of Double Dimension array to a function ` .. _funcs_n_ptrs_struct_dp_ex_0_0: .. tab-set:: .. tab-item:: Structure Double Pointer : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow struct ABC \*\*dp; .. _funcs_n_ptrs_struct_dp_ex_0_1: .. tab-set:: .. tab-item:: Structure Double Pointer : FAQs Consider a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us answer few basic questions about structure double pointer .. _funcs_n_ptrs_struct_dp_ex_6: .. tab-set:: .. tab-item:: Structure Double Pointer : fun(expression) .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If ``fun(x)`` is the function call, then ``fun(typeof(x))`` is the prototype / definition ========================== =================================== ========================================================================== Function Call Function Definition Observations ========================== =================================== ========================================================================== fun(dp[0][0]) void fun(struct ABC x) {} * Call by Value fun(dp[1][0]) void fun(struct ABC x) {} * Call by Value fun(dp[2][0]) void fun(struct ABC x) {} * Call by Value fun(&dp[0][0]) void fun(struct ABC \*p) { } * Call by Reference fun(&dp[1][0]) void fun(struct ABC \*p) { } * Call by Reference fun(&dp[2][0]) void fun(struct ABC \*p) { } * Call by Reference fun(\*\*dp) void fun(struct ABC x) {} * Call by Value fun(\*(\*(dp + 1) + 0)) void fun(struct ABC x) {} * Call by Value fun(\*(\*(dp + 2) + 0)) void fun(struct ABC x) {} * Call by Value fun(dp[0]) void fun(struct ABC \*p) { } * Call by Reference fun(dp[1]) void fun(struct ABC \*p) { } * Call by Reference fun(dp[2]) void fun(struct ABC \*p) { } * Call by Reference fun(&dp[0]) void fun(struct ABC \*\*q) { } * Call by Reference fun(\*dp) void fun(struct ABC \*p) { } * Call by Reference fun(\*(dp + 1)) void fun(struct ABC \*p) { } * Call by Reference fun(\*(dp + 2)) void fun(struct ABC \*p) { } * Call by Reference fun(dp) void fun(struct ABC \*\*q) { } * Call by Reference fun(&dp) void fun(struct ABC \*\*\*r) { } * Call by Reference ========================== =================================== ========================================================================== .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us understand the reason behind above prototypes ! .. _funcs_n_ptrs_struct_dp_ex_8: .. tab-set:: .. tab-item:: Rules for Call By Value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has two dereference operators [] [], and * Expression does not have ``&`` * then it is call by value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has two dereference operators \* \*, and * Expression does not have ``&`` * then it is call by value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has two dereference operators \* [ ], and * Expression does not have ``&`` * then it is call by value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us look at examples .. _funcs_n_ptrs_struct_dp_ex_9: .. tab-set:: .. tab-item:: Example : Call by Value : Pass Structure : dp[1][1] * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators \* and \* * Step 2 : Consider an expression ``dp[1][1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has TWO dereference operators [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note : ``[ ]`` and ``*`` are dereference operators .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression DOES NOT have ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence ``dp[1][1]`` is Call By Value .. _funcs_n_ptrs_struct_dp_ex_10: .. tab-set:: .. tab-item:: Example : Call by Value : Pass Structure : \*\*dp * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators [ ] and [ ] * Step 2 : Consider an expression ``**dp`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has TWO dereference operators \* and \* .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note : ``[ ]`` and ``*`` are dereference operators .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression DOES NOT have ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence ``**dp`` is Call By Value .. _funcs_n_ptrs_struct_dp_ex_11: .. tab-set:: .. tab-item:: Rules for Call By Reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has two dereference operators [] [] or \* \* or [] \*, and * Expression has & * then it is call by reference * Example : &dp[0][0] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has one dereference operator [ ] or \* * then it is call by reference * Example : &dp[0], dp[0], \*dp .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has two dereference operators, and * Expression has zero dereference operators, and * then it is call by reference * Example : dp, &dp .. _funcs_n_ptrs_struct_dp_ex_12: .. tab-set:: .. tab-item:: Example 1 : Call by Reference : &dp[1][1] * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has TWO dereference operators \* and \* .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note : ``[ ]`` and ``*`` are dereference operators .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression has ``&`` operator * Step 2 : Consider an expression ``&dp[1][1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence ``&dp[1][1]`` is Call By Reference .. _funcs_n_ptrs_struct_dp_ex_13: .. tab-set:: .. tab-item:: Example 2 : Call by Reference : dp[1] * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators [ ] and [ ] * Step 2 : Consider an expression ``dp[1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has ONE dereference operators .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note : ``[ ]`` and ``*`` are dereference operators .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression DOES NOT have ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence ``dp[1]`` is Call By Reference .. _funcs_n_ptrs_struct_td_array_examples_call_by_value: .. tab-set:: .. tab-item:: Examples of Call by Value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us look at examples of Call by Value .. _funcs_n_ptrs_struct_dp_ex_15: .. tab-set:: .. tab-item:: Example 1 : Call by Value : Pass Structure : dp[0][0], dp[1][0], dp[1][1] * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } * Step 2 : Assign data to structure objects .. code-block:: c int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } * Step 3 : Pass dp[0][0], dp[1][0], dp[1][1] to a function ``fun`` .. code-block:: c fun(dp[0][0]); fun(dp[1][0]); fun(dp[1][1]); * Step 4 : Define function ``fun`` .. code-block:: c void fun(struct ABC y) { y.a = 11; y.b = 22; y.c = 33; } * Step 5 : Note that it is call by Value for below reason .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has TWO dereference operators [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression DOES NOT have ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Means changing value of structure inside function DOES NOT affect value of structure in Caller ! * Step 6 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); * See full program below .. code-block:: c #include #include struct ABC { int a; int b; int c; }; void fun(struct ABC y) { y.a = 11; y.b = 22; y.c = 33; } int main(void) { struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } printf("----- Before Call By Value -----\n"); printf("dp[0][0].a = %d\n", dp[0][0].a); printf("dp[1][0].a = %d\n", dp[1][0].a); printf("dp[1][1].a = %d\n", dp[1][1].a); fun(dp[0][0]); fun(dp[1][0]); fun(dp[1][1]); printf("----- After Call By Value -----\n"); printf("dp[0][0].a = %d\n", dp[0][0].a); printf("dp[1][0].a = %d\n", dp[1][0].a); printf("dp[1][1].a = %d\n", dp[1][1].a); for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); return 0; } * Output is as below .. code-block:: c ----- Before Call By Value ----- dp[0][0].a = 99 dp[1][0].a = 111 dp[1][1].a = 114 ----- After Call By Value ----- dp[0][0].a = 99 dp[1][0].a = 111 dp[1][1].a = 114 .. _funcs_n_ptrs_struct_dp_ex_16: .. tab-set:: .. tab-item:: Example 2 : Call by Value : Pass Structure : \*\*dp, \*(\*(dp + 1) + 0), \*(\*(dp + 1) + 1) * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } * Step 2 : Assign data to structure objects .. code-block:: c int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } * Step 3 : Pass \*\*dp, \*(\*(dp + 1) + 0), \*(\*(dp + 1) + 1) to a function ``fun`` .. code-block:: c fun( **dp ); fun( *(*(dp + 1) + 0) ); fun( *(*(dp + 1) + 1) ); * Step 4 : Define function ``fun`` .. code-block:: c void fun(struct ABC y) { y.a = 11; y.b = 22; y.c = 33; } * Step 5 : Note that it is call by Value for below reason .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has TWO dereference operators [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has TWO dereference operators \* and \* .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 3 : Expression DOES NOT have ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Means changing value of structure inside function DOES NOT affect value of structure in Caller ! * Step 6 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); * See full program below .. code-block:: c #include #include struct ABC { int a; int b; int c; }; void fun(struct ABC y) { y.a = 11; y.b = 22; y.c = 33; } int main(void) { struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } printf("----- Before Call By Value -----\n"); printf(" (**dp).a = %d\n", (**dp).a ); printf(" (*(*(dp + 1) + 0)).a = %d\n", (*(*(dp + 1) + 0)).a ); printf(" (*(*(dp + 1) + 1)).a = %d\n", (*(*(dp + 1) + 1)).a ); fun( **dp ); fun( *(*(dp + 1) + 0) ); fun( *(*(dp + 1) + 1) ); printf("----- After Call By Value -----\n"); printf(" (**dp).a = %d\n", (**dp).a ); printf(" (*(*(dp + 1) + 0)).a = %d\n", (*(*(dp + 1) + 0)).a ); printf(" (*(*(dp + 1) + 1)).a = %d\n", (*(*(dp + 1) + 1)).a ); for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); return 0; } * Output is as below .. code-block:: c ----- Before Call By Value ----- (**dp).a = 99 (*(*(dp + 1) + 0)).a = 111 (*(*(dp + 1) + 1)).a = 114 ----- After Call By Value ----- (**dp).a = 99 (*(*(dp + 1) + 0)).a = 111 (*(*(dp + 1) + 1)).a = 114 .. _funcs_n_ptrs_struct_td_array_examples_call_by_reference: .. tab-set:: .. tab-item:: Examples of Call by Reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us look at examples of Call by Reference .. _funcs_n_ptrs_struct_dp_ex_17: .. tab-set:: .. tab-item:: Example 3 : Call by Reference : Pass Single dimension arrays which are part of a double dimension array to a function * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow There are 3 single dimension arrays * dp[0] * dp[1] * dp[2] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow dp[0] is also equal to \*dp dp[1] is also equal to \*(dp + 1) dp[2] is also equal to \*(dp + 2) .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow dp[0] is also equal to &dp[0][0] dp[1] is also equal to &dp[1][0] dp[2] is also equal to &dp[2][0] * Step 2 : Assign data to structure objects .. code-block:: c int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } * Step 3.1 : Method 1 : Pass &dp[0][0], &dp[1][0], &dp[2][0] to a function ``fun`` .. code-block:: c fun( &dp[0][0] ); fun( &dp[1][0] ); fun( &dp[2][0] ); * Step 3.2 : Method 2 : Pass dp[0], dp[1], dp[2] to a function ``fun`` .. code-block:: c fun( dp[0] ); fun( dp[1] ); fun( dp[2] ); * Step 3.3 : Method 3 : Pass \*dp, \*(dp + 1), \*(dp + 2) to a function ``fun`` .. code-block:: c fun( *dp ); fun( *(dp + 1) ); fun( *(dp + 2) ); * Step 4 : Define function ``fun`` .. code-block:: c void fun(struct ABC *ptr) { } * Step 5 : Note that it is call by Reference. Means contents of single dimension array can be changed inside function ``fun`` .. code-block:: c void fun(struct ABC *ptr) { int data = 666; for (int i = 0; i< 4; i++) { ptr[i].a = data++; ptr[i].b = data++; ptr[i].c = data++; } } * Step 6 : Free memory after usage .. code-block:: c for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); * See full program below .. code-block:: c #include #include struct ABC { int a; int b; int c; }; void fun(struct ABC *ptr) { int data = 666; for (int i = 0; i< 4; i++) { ptr[i].a = data++; ptr[i].b = data++; ptr[i].c = data++; } } int main(void) { struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } printf("----- Before Call By Reference -----\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("dp[%d][%d].a = %d ", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d ", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d ", i, j, dp[i][j].c); printf("\n"); } printf("\n"); } // Method 1 : Access Single dimension arrays fun( &dp[0][0] ); fun( &dp[1][0] ); fun( &dp[2][0] ); // Method 2 : Access Single dimension arrays fun( dp[0] ); fun( dp[1] ); fun( dp[2] ); // Method 3 : Access Single dimension arrays fun( *dp ); fun( *(dp + 1) ); fun( *(dp + 2) ); printf("----- After Call By Reference -----\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("dp[%d][%d].a = %d ", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d ", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d ", i, j, dp[i][j].c); printf("\n"); } printf("\n"); } for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); return 0; } * Output is as below .. code-block:: c ----- Before Call By Reference ----- dp[0][0].a = 99 dp[0][0].b = 100 dp[0][0].c = 101 dp[0][1].a = 102 dp[0][1].b = 103 dp[0][1].c = 104 dp[0][2].a = 105 dp[0][2].b = 106 dp[0][2].c = 107 dp[0][3].a = 108 dp[0][3].b = 109 dp[0][3].c = 110 dp[1][0].a = 111 dp[1][0].b = 112 dp[1][0].c = 113 dp[1][1].a = 114 dp[1][1].b = 115 dp[1][1].c = 116 dp[1][2].a = 117 dp[1][2].b = 118 dp[1][2].c = 119 dp[1][3].a = 120 dp[1][3].b = 121 dp[1][3].c = 122 dp[2][0].a = 123 dp[2][0].b = 124 dp[2][0].c = 125 dp[2][1].a = 126 dp[2][1].b = 127 dp[2][1].c = 128 dp[2][2].a = 129 dp[2][2].b = 130 dp[2][2].c = 131 dp[2][3].a = 132 dp[2][3].b = 133 dp[2][3].c = 134 ----- After Call By Reference ----- dp[0][0].a = 666 dp[0][0].b = 667 dp[0][0].c = 668 dp[0][1].a = 669 dp[0][1].b = 670 dp[0][1].c = 671 dp[0][2].a = 672 dp[0][2].b = 673 dp[0][2].c = 674 dp[0][3].a = 675 dp[0][3].b = 676 dp[0][3].c = 677 dp[1][0].a = 666 dp[1][0].b = 667 dp[1][0].c = 668 dp[1][1].a = 669 dp[1][1].b = 670 dp[1][1].c = 671 dp[1][2].a = 672 dp[1][2].b = 673 dp[1][2].c = 674 dp[1][3].a = 675 dp[1][3].b = 676 dp[1][3].c = 677 dp[2][0].a = 666 dp[2][0].b = 667 dp[2][0].c = 668 dp[2][1].a = 669 dp[2][1].b = 670 dp[2][1].c = 671 dp[2][2].a = 672 dp[2][2].b = 673 dp[2][2].c = 674 dp[2][3].a = 675 dp[2][3].b = 676 dp[2][3].c = 677 .. _funcs_n_ptrs_struct_dp_ex_19: .. tab-set:: .. tab-item:: Example 4 : Call by Reference : Pass Address of Double Dimension array to a function * Step 1 : Consider a double dimension array created using a structure double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } * Step 2 : Assign data to structure objects .. code-block:: c int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } * Step 2 : Pass Address of Double Dimension array to a function .. code-block:: c fun(&dp); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(struct ABC ***ptr ) { } * Step 3.2 : Access and change individual structures inside function ``fun`` .. code-block:: c int data = 666; for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 4; j++) { (*ptr)[i][j].a = data++; (*ptr)[i][j].b = data++; (*ptr)[i][j].c = data++; } } * Step 4 : Free memory after usage .. code-block:: c for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); * See full program below .. code-block:: c #include #include struct ABC { int a; int b; int c; }; void fun(struct ABC ***ptr) { int data = 666; for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 4; j++) { (*ptr)[i][j].a = data++; (*ptr)[i][j].b = data++; (*ptr)[i][j].c = data++; } } } int main(void) { struct ABC **dp; dp = malloc(3 * sizeof(struct ABC *)); for (int i = 0; i < 3; i++) { dp[i] = malloc(4 * sizeof(struct ABC)); } int data = 99; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { dp[i][j].a = data++; dp[i][j].b = data++; dp[i][j].c = data++; } } printf("----- Before Call By Reference -----\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("dp[%d][%d].a = %d ", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d ", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d ", i, j, dp[i][j].c); printf("\n"); } printf("\n"); } fun(&dp); printf("----- After Call By Reference -----\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("dp[%d][%d].a = %d ", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d ", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d ", i, j, dp[i][j].c); printf("\n"); } printf("\n"); } for (int i = 0; i < 3; i++) { free(dp[i]); } free(dp); return 0; } * Output is as below .. code-block:: c ----- Before Call By Reference ----- dp[0][0].a = 99 dp[0][0].b = 100 dp[0][0].c = 101 dp[0][1].a = 102 dp[0][1].b = 103 dp[0][1].c = 104 dp[0][2].a = 105 dp[0][2].b = 106 dp[0][2].c = 107 dp[0][3].a = 108 dp[0][3].b = 109 dp[0][3].c = 110 dp[1][0].a = 111 dp[1][0].b = 112 dp[1][0].c = 113 dp[1][1].a = 114 dp[1][1].b = 115 dp[1][1].c = 116 dp[1][2].a = 117 dp[1][2].b = 118 dp[1][2].c = 119 dp[1][3].a = 120 dp[1][3].b = 121 dp[1][3].c = 122 dp[2][0].a = 123 dp[2][0].b = 124 dp[2][0].c = 125 dp[2][1].a = 126 dp[2][1].b = 127 dp[2][1].c = 128 dp[2][2].a = 129 dp[2][2].b = 130 dp[2][2].c = 131 dp[2][3].a = 132 dp[2][3].b = 133 dp[2][3].c = 134 ----- After Call By Reference ----- dp[0][0].a = 666 dp[0][0].b = 667 dp[0][0].c = 668 dp[0][1].a = 669 dp[0][1].b = 670 dp[0][1].c = 671 dp[0][2].a = 672 dp[0][2].b = 673 dp[0][2].c = 674 dp[0][3].a = 675 dp[0][3].b = 676 dp[0][3].c = 677 dp[1][0].a = 678 dp[1][0].b = 679 dp[1][0].c = 680 dp[1][1].a = 681 dp[1][1].b = 682 dp[1][1].c = 683 dp[1][2].a = 684 dp[1][2].b = 685 dp[1][2].c = 686 dp[1][3].a = 687 dp[1][3].b = 688 dp[1][3].c = 689 dp[2][0].a = 690 dp[2][0].b = 691 dp[2][0].c = 692 dp[2][1].a = 693 dp[2][1].b = 694 dp[2][1].c = 695 dp[2][2].a = 696 dp[2][2].b = 697 dp[2][2].c = 698 dp[2][3].a = 699 dp[2][3].b = 700 dp[2][3].c = 701 .. card:: See Also * Other topics of structure and functions * :doc:`./struct` * :doc:`./struct_sd_array` * :doc:`./struct_dd_array` * :doc:`./struct_td_array` * :doc:`./struct_sp` * :doc:`./struct_dp` * :doc:`./struct_tp` * Current Module * :doc:`../funcs_n_ptrs` * Previous Module * :doc:`../../typecasting_n_ptr/typecasting_n_ptr` * Next Module * :doc:`../../memcpy_ptr/memcpy_ptr` * Other Modules * :doc:`../../variable_and_ptr/variable_and_ptr` * :doc:`../../array_n_ptrs/array_n_ptrs` * :doc:`../../malloc_ptr/malloc_ptr` * :doc:`../../const_ptr/const_ptr` * :doc:`../../void_ptr/void_ptr` * :doc:`../../array_of_ptr/array_of_ptr` * :doc:`../../ptr_to_array/ptr_to_array` * :doc:`../../function_ptr/function_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`