Functions and Character Double Dimension Array ================================================== 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 character 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:`../../array_n_ptrs/arrays_n_chars/char_dd_array` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Character Double Dimension Array : Syntax ` * :ref:`Character Double Dimension Array : FAQs ` * :ref:`Character Double Dimension Array : fun(expression) ` * :ref:`Rules for Call By Value ` * :ref:`Example : Call by Value : Pass Character : a[1][1] ` * :ref:`Example : Call by Value : Pass Character : **a ` * :ref:`Rules for Call By Reference ` * :ref:`Example : Call by Reference : &a[1][1] ` * :ref:`Example : Call by Reference : a[1] ` * :ref:`Examples of Call by Value ` * :ref:`Example 1 : Call by Value : Pass Character : a[0][0], a[1][0], a[1][1] ` * :ref:`Example 2 : Call by Value : Pass Character : **a, *(*(a + 1) + 0), *(*(a + 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 Single dimension arrays which are part of a double dimension array to a function ` * :ref:`Example 5 : Call by Reference : Pass Address of Double Dimension array to a function ` .. _funcs_n_ptrs_char_dd_array_ex_0_0: .. tab-set:: .. tab-item:: Character Double Dimension Array : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow char array_name[Row][Column]; .. _funcs_n_ptrs_char_dd_array_ex_0_1: .. tab-set:: .. tab-item:: Character Double Dimension Array : FAQs Consider a character double dimension array .. code-block:: c char a[3][4]; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us answer few basic questions in this array .. _funcs_n_ptrs_char_dd_array_ex_6: .. tab-set:: .. tab-item:: Character Double Dimension Array : 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(a[0][0]) void fun(char x) {} * Call by Value fun(a[1][0]) void fun(char x) {} * Call by Value fun(a[2][0]) void fun(char x) {} * Call by Value fun(&a[0][0]) void fun(char \*p) { } * Call by Reference fun(&a[1][0]) void fun(char \*p) { } * Call by Reference fun(&a[2][0]) void fun(char \*p) { } * Call by Reference fun(\*\*a) void fun(char x) {} * Call by Value fun(\*(\*(a + 1) + 0)) void fun(char x) {} * Call by Value fun(\*(\*(a + 2) + 0)) void fun(char x) {} * Call by Value fun(a[0]) void fun(char \*p) { } * Call by Reference fun(a[1]) void fun(char \*p) { } * Call by Reference fun(a[2]) void fun(char \*p) { } * Call by Reference fun(&a[0]) void fun(char (\*p)[4]) { } * Call by Reference fun(&a[1]) void fun(char (\*p)[4]) { } * Call by Reference fun(&a[2]) void fun(char (\*p)[4]) { } * Call by Reference fun(\*a) void fun(char \*p) { } * Call by Reference fun(\*(a + 1)) void fun(char \*p) { } * Call by Reference fun(\*(a + 2)) void fun(char \*p) { } * Call by Reference fun(a) void fun(char (\*p)[4]) { } * Call by Reference fun(a + 1) void fun(char (\*p)[4]) { } * Call by Reference fun(a + 2) void fun(char (\*p)[4]) { } * Call by Reference fun(&a) void fun(char (\*p)[3][4]) { } * 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_char_dd_array_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_char_dd_array_ex_9: .. tab-set:: .. tab-item:: Example 1 : Call by Value : Pass Character : a[1][1] * Step 1 : Consider an array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. 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 ``a[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 ``a[1][1]`` is Call By Value .. _funcs_n_ptrs_char_dd_array_ex_10: .. tab-set:: .. tab-item:: Example 2 : Call by Value : Pass Character : \*\*a * Step 1 : Consider an array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. 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 ``**a`` .. 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 ``**a`` is Call By Value .. _funcs_n_ptrs_char_dd_array_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 : &a[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 \*, and * then it is call by reference * Example : &a[0], a[0], \*a .. 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 : a, &a, a + 1, a + 2 .. _funcs_n_ptrs_char_dd_array_ex_12: .. tab-set:: .. tab-item:: Example 1 : Call by Reference : &a[1][1] * Step 1 : Consider an array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. 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 ``&a[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 has ``&`` operator .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence ``&a[1][1]`` is Call By Reference .. _funcs_n_ptrs_char_dd_array_ex_13: .. tab-set:: .. tab-item:: Example 2 : Call by Reference : a[1] * Step 1 : Consider an array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. 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 ``a[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 ``a[1]`` is Call By Reference .. _funcs_n_ptrs_char_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_char_dd_array_ex_15: .. tab-set:: .. tab-item:: Example 1 : Call by Value : Pass Character : a[0][0], a[1][0], a[1][1] * Step 1 : Consider a two dimensional array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; * Step 2 : Pass a[0][0], a[1][0], a[1][1] to a function ``fun`` .. code-block:: c fun(a[0][0]); fun(a[1][0]); fun(a[1][1]); * Step 3 : Define function ``fun`` .. code-block:: c void fun(char c) { printf("char is %c\n", c); c = 'k'; } * Step 4 : 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 character inside function DOES NOT affect value of character in Caller ! * See full program below .. code-block:: c #include void fun(char c) { printf("char is %c\n", c); } int main(void) { char a[3][4] = { "lap", "top", "123" }; fun(a[0][0]); fun(a[1][0]); fun(a[1][1]); return 0; } * Output is as below .. code-block:: c char is l char is t char is o .. _funcs_n_ptrs_char_dd_array_ex_16: .. tab-set:: .. tab-item:: Example 2 : Call by Value : Pass Character : \*\*a, \*(\*(a + 1) + 0), \*(\*(a + 1) + 1) * Step 1 : Consider a two dimensional array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; * Step 2 : Pass \*\*a, \*(\*(a + 1) + 0), \*(\*(a + 1) + 1) to a function ``fun`` .. code-block:: c fun( **a ); fun( *(*(a + 1) + 0) ); fun( *(*(a + 1) + 1) ); * Step 3 : Define function ``fun`` .. code-block:: c void fun(char c) { printf("char is %c\n", c); c = 'k'; } * Step 4 : 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 character inside function DOES NOT affect value of character in Caller ! * See full program below .. code-block:: c #include void fun(char c) { printf("char is %c\n", c); } int main(void) { char a[3][4] = { "lap", "top", "123" }; fun( **a ); fun( *(*(a + 1) + 0) ); fun( *(*(a + 1) + 1) ); return 0; } * Output is as below .. code-block:: c char is l char is t char is o .. _funcs_n_ptrs_char_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_char_dd_array_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 two dimensional array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow There are 3 single dimension arrays in ``char a[3][4]`` * a[0] * a[1] * a[2] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow a[0] is also equal to \*a a[1] is also equal to \*(a + 1) a[2] is also equal to \*(a + 2) .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow a[0] is also equal to &a[0][0] a[1] is also equal to &a[1][0] a[2] is also equal to &a[2][0] * Step 2.1 : Method 1 : Pass &a[0][0], &a[1][0], &a[2][0] to a function ``fun`` .. code-block:: c fun( &a[0][0] ); fun( &a[1][0] ); fun( &a[2][0] ); * Step 2.2 : Method 2 : Pass a[0], a[1], a[2] to a function ``fun`` .. code-block:: c fun( a[0] ); fun( a[1] ); fun( a[2] ); * Step 2.3 : Method 3 : Pass \*a, \*(a + 1), \*(a + 2) to a function ``fun`` .. code-block:: c fun( *a ); fun( *(a + 1) ); fun( *(a + 2) ); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(char *ptr) { printf("string is %s\n", ptr); } * Step 4 : Note that it is call by Reference. Means contents of single dimension array can be changed inside function ``fun`` .. code-block:: c void fun(char *ptr) { strcpy(ptr, "123"); } * See full program below .. code-block:: c #include void fun(char *ptr) { printf("string is %s\n", ptr); } int main(void) { char a[3][4] = { "lap", "top", "123" }; printf("Method 1 : Access Single dimension arrays\n"); fun( &a[0][0] ); fun( &a[1][0] ); fun( &a[2][0] ); printf("Method 2 : Access Single dimension arrays\n"); fun( a[0] ); fun( a[1] ); fun( a[2] ); printf("Method 3 : Access Single dimension arrays\n"); fun( *a ); fun( *(a + 1) ); fun( *(a + 2) ); return 0; } * Output is as below .. code-block:: c Method 1 : Access Single dimension arrays string is lap string is top string is 123 Method 2 : Access Single dimension arrays string is lap string is top string is 123 Method 3 : Access Single dimension arrays string is lap string is top string is 123 .. _funcs_n_ptrs_char_dd_array_ex_18: .. tab-set:: .. tab-item:: Example 4 : Call by Reference : Pass Address of Single dimension arrays which are part of a double dimension array to a function * Step 1 : Consider a two dimensional array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow There are 3 single dimension arrays in ``char a[3][4]`` * a[0] * a[1] * a[2] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Address of single dimension arrays is simply * &a[0] * &a[1] * &a[2] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * &a[0] is also equal to a * &a[1] is also equal to a + 1 * &a[2] is also equal to a + 2 * Step 2.1 : Method 1 : Pass address of single dimension arrays to a function ``fun`` .. code-block:: c fun( &a[0] ); fun( &a[1] ); fun( &a[2] ); * Step 2.2 : Method 2 : Pass address of single dimension arrays to a function ``fun`` .. code-block:: c fun( a ); fun( a + 1 ); fun( a + 2 ); * Step 3.1 : Define the function ``fun`` .. code-block:: c void fun(char (*ptr)[4] ) { printf("string is %s\n", *ptr); } * Step 3.2 : Define the function ``fun`` to change the contents of single dimension array .. code-block:: c void fun(char (*ptr)[4] ) { printf("string is %s\n", *ptr); strcpy((char *)ptr, "Gap"); } * Step 3.3 : Define the function ``fun`` to change the contents of single dimension array character by character .. code-block:: c void fun(char (*ptr)[4] ) { printf("string is %s\n", *ptr); strcpy((char *)ptr, "Gap"); (*ptr)[0] = 'p'; (*ptr)[1] = 'g'; (*ptr)[2] = 'x'; (*ptr)[3] = '\0'; } * See full program below .. code-block:: c #include void fun(char (*ptr)[4] ) { printf("string is %s\n", *ptr); strcpy((char *)ptr, "Gap"); (*ptr)[0] = 'p'; (*ptr)[1] = 'g'; (*ptr)[2] = 'x'; (*ptr)[3] = '\0'; } int main(void) { char a[3][4] = { "lap", "top", "123" }; printf("Method 1 : Access Single dimension arrays\n"); fun( &a[0] ); fun( &a[1] ); fun( &a[2] ); printf("Method 2 : Access Single dimension arrays\n"); fun( a ); fun( a + 1 ); fun( a + 2 ); return 0; } * Output is as below .. code-block:: c Method 1 : Access Single dimension arrays string is lap string is top string is 123 Method 2 : Access Single dimension arrays string is pgx string is pgx string is pgx .. _funcs_n_ptrs_char_dd_array_ex_19: .. tab-set:: .. tab-item:: Example 5 : Call by Reference : Pass Address of Double Dimension array to a function * Step 1 : Consider a two dimensional array .. code-block:: c char a[3][4] = { "lap", "top", "123" }; * Step 2 : Pass Address of Double Dimension array to a function .. code-block:: c fun(&a); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(char (*ptr)[3][4] ) { } * Step 3.2 : Access and Print the strings inside function ``fun`` .. code-block:: c for (int i = 0 ; i < 3; i++) { printf("%s\n", (*ptr)[i]); } * Step 3.3 : Access and Print individual characters inside function ``fun`` .. code-block:: c for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 3; j++) { printf("%c\n", (*ptr)[i][j]); } } * Step 3.4 : Access and change strings inside function ``fun`` .. code-block:: c for (int i = 0 ; i < 3; i++) { strcpy( (*ptr)[i], "pgx" ); } * Step 3.5 : Access and change individual characters inside function ``fun`` .. code-block:: c for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 3; j++) { (*ptr)[i][j] = 'c'; } } * See full program below .. code-block:: c #include #include void fun(char (*ptr)[3][4] ) { // Print Individual strings for (int i = 0 ; i < 3; i++) { printf("%s\n", (*ptr)[i]); } // Print Individual characters for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 3; j++) { printf("%c\n", (*ptr)[i][j]); } } // Change Individual strings for (int i = 0 ; i < 3; i++) { strcpy( (*ptr)[i], "pgx" ); } // Change Individual characters for (int i = 0 ; i < 3; i++) { for (int j = 0 ; j < 3; j++) { (*ptr)[i][j] = 'c'; } } // Print Individual strings for (int i = 0 ; i < 3; i++) { printf("%s\n", (*ptr)[i]); } } int main(void) { char a[3][4] = { "lap", "top", "123" }; fun(&a); return 0; } * Output is as below .. code-block:: c lap top 123 l a p t o p 1 2 3 ccc ccc ccc .. card:: See Also * Other topics of character and functions * :doc:`./char` * :doc:`./char_sd_array` * :doc:`./char_dd_array` * :doc:`./char_td_array` * :doc:`./char_sp` * :doc:`./char_dp` * :doc:`./char_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`