Functions and Character Triple 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 character triple pointer ? .. 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_char_ptr/char_tp` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Character Triple Pointer : Syntax ` * :ref:`Character Triple Pointer : FAQs ` * :ref:`Character Triple Pointer : fun(expression) ` * :ref:`Rules for Call By Value ` * :ref:`Example : Call by Value : Pass Character : tp[1][1][1] ` * :ref:`Example : Call by Value : Pass Character : ***tp ` * :ref:`Rules for Call By Reference ` * :ref:`Example : Call by Reference : &tp[1][1] ` * :ref:`Example : Call by Reference : tp[1] ` * :ref:`Examples of Call by Value ` * :ref:`Example 1 : Call by Value : Pass Character : tp[0][0][0], tp[1][0][0], tp[2][0][0] ` * :ref:`Example 2 : Call by Value : Pass Character : \*\*\*tp, \*(\*(\*(tp + 1) + 0) + 0), \*(\*(\*(tp + 2) + 0) + 0) ` * :ref:`Examples of Call by Reference ` * :ref:`Example 3 : Call by Reference : Pass Single dimension arrays which are part of a triple pointer to a function ` * :ref:`Example 4 : Call by Reference : Pass Address of Single dimension arrays which are part of a triple pointer to a function ` * :ref:`Example 5 : Call by Reference : Pass Double dimension arrays which are part of a Triple dimension array to a function ` * :ref:`Example 6 : Call by Reference : Pass Address of Double dimension arrays which are part of a Triple dimension array to a function ` * :ref:`Example 7 : Call by Reference : Pass Address of Triple Dimension array to a function ` .. _funcs_n_ptrs_char_tp_ex_0: .. tab-set:: .. tab-item:: Character Triple Pointer : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow char \*\*\*tp; .. _funcs_n_ptrs_char_tp_ex_0_1: .. tab-set:: .. tab-item:: Character Triple Pointer : FAQs Consider a character triple pointer .. code-block:: c char ***tp; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us answer few basic questions about character triple pointer .. _funcs_n_ptrs_char_tp_ex_6: .. tab-set:: .. tab-item:: Character Triple 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(tp[0][0][0]) void fun(char x) {} * Call by Value fun(tp[1][0][0]) void fun(char x) {} * Call by Value fun(tp[2][0][0]) void fun(char x) {} * Call by Value fun(&tp[0][0][0]) void fun(char \*p) {} * Call by Reference fun(&tp[1][0][0]) void fun(char \*p) {} * Call by Reference fun(&tp[2][0][0]) void fun(char \*p) {} * Call by Reference fun(tp[0][0]) void fun(char \*p) {} * Call by Reference fun(tp[1][0]) void fun(char \*p) {} * Call by Reference fun(tp[2][0]) void fun(char \*p) {} * Call by Reference fun(&tp[0][0]) void fun(char \*\*p) {} * Call by Reference fun(&tp[1][0]) void fun(char \*\*p) {} * Call by Reference fun(&tp[2][0]) void fun(char \*\*p) {} * Call by Reference fun(\*\*tp) void fun(char \*p) {} * Call by Reference fun(\*(\*(tp + 1) + 0)) void fun(char \*p) {} * Call by Reference fun(\*(\*(tp + 2) + 0)) void fun(char \*p) {} * Call by Reference fun(tp[0]) void fun(char \*\*p) {} * Call by Reference fun(tp[1]) void fun(char \*\*p) {} * Call by Reference fun(tp[2]) void fun(char \*\*p) {} * Call by Reference fun(&tp[0]) void fun(char \*\*\*p) {} * Call by Reference fun(\*tp) void fun(char \*\*p) {} * Call by Reference fun(\*(tp + 1)) void fun(char \*\*p) {} * Call by Reference fun(\*(tp + 2)) void fun(char \*\*p) {} * Call by Reference fun(tp) void fun(char \*\*\*p) {} * Call by Reference fun(&tp) void fun(char \*\*\*\*p) {} * 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_tp_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 THREE dereference operators, and * Expression has THREE 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 THREE dereference operators, and * Expression has THREE 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 THREE dereference operators, and * Expression has THREE 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 THREE dereference operators, and * Expression has THREE 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_tp_ex_9: .. tab-set:: .. tab-item:: Example 1 : Call by Value : Pass Character : tp[1][1][1] * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ] * Step 2 : Consider an expression ``tp[1][1][1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has THREE 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 ``tp[1][1][1]`` is Call By Value .. _funcs_n_ptrs_char_tp_ex_10: .. tab-set:: .. tab-item:: Example 2 : Call by Value : Pass Character : \*\*\*tp * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ] * Step 2 : Consider an expression ``***tp`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has THREE 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 ``***tp`` is Call By Value .. _funcs_n_ptrs_char_tp_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 THREE dereference operators, and * Expression has THREE dereference operators \* \* \* OR \* \* [] OR \* [] [] OR [] [] [] and * Expression has & * then it is call by reference * Example : &tp[0][0][0], &tp[1][2][3] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has THREE dereference operators, and * Expression has TWO dereference operator \* \* OR [] [] OR \* [] * then it is call by reference * Example : tp[0][0] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has THREE dereference operators, and * Expression has ONE dereference operators, \* OR [ ] * then it is call by reference * Example : tp[0] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has THREE dereference operators, and * Expression has ZERO dereference operators * then it is call by reference * Example : tp .. _funcs_n_ptrs_char_tp_ex_12: .. tab-set:: .. tab-item:: Example 1 : Call by Reference : &tp[1][1][1] * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ] * Step 2 : Consider an expression ``&tp[1][1][1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has THREE 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 ``&tp[1][1][1]`` is Call By Reference .. _funcs_n_ptrs_char_tp_ex_13: .. tab-set:: .. tab-item:: Example 2 : Call by Reference : tp[1] * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ] * Step 2 : Consider an expression ``tp[1]`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has ONE dereference operator .. 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 ``tp[1]`` is Call By Reference .. _funcs_n_ptrs_char_tp_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_tp_ex_15: .. tab-set:: .. tab-item:: Example 1 : Call by Value : Pass Character : tp[0][0][0], tp[1][0][0], tp[2][0][0] * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); * Step 2 : Pass tp[0][0][0], tp[1][0][0], tp[2][0][0] to a function ``fun`` .. code-block:: c fun(tp[0][0][0]); fun(tp[1][0][0]); fun(tp[2][0][0]); * 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 THREE dereference operators [ ] [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has THREE 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 ! * Step 5 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * See full program below .. code-block:: c #include #include #include void fun(char c) { printf("char is %c\n", c); c = 'k'; } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); fun(tp[0][0][0]); fun(tp[1][0][0]); fun(tp[2][0][0]); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Output is as below .. code-block:: c char is l char is g char is s .. _funcs_n_ptrs_char_tp_ex_16: .. tab-set:: .. tab-item:: Example 2 : Call by Value : Pass Character : \*\*\*tp, \*(\*(\*(tp + 1) + 0) + 0), \*(\*(\*(tp + 2) + 0) + 0) * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); * Step 2 : Pass \*\*\*tp, \*(\*(\*(tp + 1) + 0) + 0), \*(\*(\*(tp + 2) + 0) + 0) to a function ``fun`` .. code-block:: c fun( ***tp ); fun( *(*(*(tp + 1) + 0) + 0) ); fun( *(*(*(tp + 2) + 0) + 0) ); * 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 THREE dereference operators [ ] [ ] and [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Condition 2 : Expression has THREE 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 ! * Step 5 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * See full program below .. code-block:: c #include #include #include void fun(char c) { printf("char is %c\n", c); } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); fun( ***tp ); fun( *(*(*(tp + 1) + 0) + 0) ); fun( *(*(*(tp + 2) + 0) + 0) ); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Output is as below .. code-block:: c char is l char is g char is s .. _funcs_n_ptrs_char_tp_examples_call_by_reference: .. 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 Reference .. _funcs_n_ptrs_char_tp_ex_17: .. tab-set:: .. tab-item:: Example 3 : Call by Reference : Pass Single dimension arrays which are part of a triple pointer to a function * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow There are 12 single dimension arrays in ``char \*\*\*tp`` with respect to above allocation tp[0][0] tp[0][1] tp[0][2] tp[0][3] tp[1][0] tp[1][1] tp[1][2] tp[1][3] tp[2][0] tp[2][1] tp[2][2] tp[2][3] * Step 2.1 : Method 1 : Pass tp[0][0], tp[1][0], tp[2][0] to a function ``fun`` .. code-block:: c fun( tp[0][0] ); fun( tp[1][0] ); fun( tp[2][0] ); * Step 2.2 : Method 2 : Pass &tp[0][0][0], &tp[1][0][0], &tp[2][0][0] to a function ``fun`` .. code-block:: c fun( &tp[0][0][0] ); fun( &tp[1][0][0] ); fun( &tp[2][0][0] ); * Step 2.3 : Method 3 : Pass \*\*tp, \*(\*(tp + 1) + 0), \*(\*(tp + 2) + 0) to a function ``fun`` .. code-block:: c fun( **tp ); fun( *(*(tp + 1) + 0) ); fun( *(*(tp + 2) + 0) ); * 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"); } * Step 5 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * See full program below .. code-block:: c #include #include #include void fun(char *ptr) { printf("string is %s\n", ptr); } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); printf("Method 1 : Access Single dimension arrays\n"); fun( tp[0][0] ); fun( tp[1][0] ); fun( tp[2][0] ); printf("Method 2 : Access Single dimension arrays\n"); fun( &tp[0][0][0] ); fun( &tp[1][0][0] ); fun( &tp[2][0][0] ); printf("Method 3 : Access Single dimension arrays\n"); fun( **tp ); fun( *(*(tp + 1) + 0) ); fun( *(*(tp + 2) + 0) ); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Output is as below .. code-block:: c Method 1 : Access Single dimension arrays string is lap0 string is gap0 string is sap0 Method 2 : Access Single dimension arrays string is lap0 string is gap0 string is sap0 Method 3 : Access Single dimension arrays string is lap0 string is gap0 string is sap0 .. _funcs_n_ptrs_char_tp_ex_18: .. tab-set:: .. tab-item:: Example 4 : Call by Reference : Pass Address of Single dimension arrays which are part of a triple pointer to a function * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow There are 12 single dimension arrays in tp[0][0] tp[0][1] tp[0][2] tp[0][3] tp[1][0] tp[1][1] tp[1][2] tp[1][3] tp[2][0] tp[2][1] tp[2][2] tp[2][3] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Address of single dimension arrays is simply &tp[0][0] &tp[0][1] &tp[0][2] &tp[0][3] &tp[1][0] &tp[1][1] &tp[1][2] &tp[1][3] &tp[2][0] &tp[2][1] &tp[2][2] &tp[2][3] * Step 2.1 : Method 1 : Pass address of single dimension arrays to a function ``fun`` .. code-block:: c fun( &tp[0][0] ); fun( &tp[1][0] ); fun( &tp[2][0] ); * Step 2.2 : Method 2 : Pass address of single dimension arrays to a function ``fun`` .. code-block:: c fun( tp[0] ); fun( tp[1] ); fun( tp[2] ); * Step 2.3 : Method 2 : Pass address of single dimension arrays to a function ``fun`` .. code-block:: c fun( *tp ); fun( *(tp + 1) ); fun( *(tp + 2) ); * Step 3.1 : Define the function ``fun`` .. code-block:: c void fun(char **ptr ) { 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 ) { 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) { strcpy((char *)*ptr, "Gap"); (*ptr)[0] = 'p'; (*ptr)[1] = 'g'; (*ptr)[2] = 'x'; (*ptr)[3] = 'y'; (*ptr)[4] = '\0'; printf("string is %s\n", *ptr); } * Step 4 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * See full program below .. code-block:: c #include #include #include void fun(char **ptr ) { strcpy((char *)*ptr, "Gap"); (*ptr)[0] = 'p'; (*ptr)[1] = 'g'; (*ptr)[2] = 'x'; (*ptr)[3] = 'y'; (*ptr)[4] = '\0'; printf("string is %s\n", *ptr); } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); printf("Method 1 : Access Single dimension arrays\n"); fun( &tp[0][0] ); fun( &tp[1][0] ); fun( &tp[2][0] ); printf("Method 2 : Access Single dimension arrays\n"); fun( tp[0] ); fun( tp[1] ); fun( tp[2] ); printf("Method 3 : Access Single dimension arrays\n"); fun( *tp ); fun( *(tp + 1) ); fun( *(tp + 2) ); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Output is as below .. code-block:: c Method 1 : Access Single dimension arrays string is pgxy string is pgxy string is pgxy Method 2 : Access Single dimension arrays string is pgxy string is pgxy string is pgxy Method 3 : Access Single dimension arrays string is pgxy string is pgxy string is pgxy .. _funcs_n_ptrs_char_tp_ex_19: .. tab-set:: .. tab-item:: Example 5 : Call by Reference : Pass Double dimension arrays which are part of a Triple dimension array to a function * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); * Step 2 : Pass Double dimension array to function ``fun`` .. code-block:: c fun(tp[1]); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(char **ptr) { } * Step 3.2 : Access and Print strings inside function ``fun`` .. code-block:: c void fun(char **ptr) { for(int i = 0; i < 4; i++) { printf("%s", ptr[i]); printf("\n"); } } * Step 3.3 : Access and Print characters inside function ``fun`` .. code-block:: c void fun(char **ptr) { for(int i = 0; i < 4; i++) { for(int j = 0; j < 5; j++) { printf("%c", ptr[i][j]); } printf("\n"); } } * Step 3.4 : Access and Change strings inside function ``fun`` .. code-block:: c void fun(char **ptr) { for(int i = 0; i < 4; i++) { strncpy(ptr[i], "gggg", 5); } } * Step 3.5 : Access and Change characters inside function ``fun`` .. code-block:: c void fun(char **ptr) { for(int i = 0; i < 4; i++) { for(int j = 0; j < 5 - 1; j++) { ptr[i][j] = 'c'; } } } * Step 4 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * Step 5 : See the full program below .. code-block:: c #include #include #include void fun(char **ptr) { // Access Strings and Print printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", ptr[i]); printf("\n"); } // Access Characters and Print printf("fun() : Access Characters and Print\n"); for(int i = 0; i < 4; i++) { for(int j = 0; j < 5; j++) { printf("%c", ptr[i][j]); } printf("\n"); } //Access Strings and Change for(int i = 0; i < 4; i++) { strncpy(ptr[i], "gggg", 5); } printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", ptr[i]); printf("\n"); } // Access Characters and Change for(int i = 0; i < 4; i++) { for(int j = 0; j < 5 - 1; j++) { ptr[i][j] = 'c'; } } printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", ptr[i]); printf("\n"); } } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); fun(tp[1]); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } return 0; } * Step 5 : Output is as below .. code-block:: c fun() : Access Strings and Print gap0 pop0 yyy0 4560 fun() : Access Characters and Print gap0 pop0 yyy0 4560 fun() : Access Strings and Print gggg gggg gggg gggg fun() : Access Strings and Print cccc cccc cccc cccc .. _funcs_n_ptrs_char_tp_ex_20: .. tab-set:: .. tab-item:: Example 6 : Call by Reference : Pass address of Double dimension arrays which are part of a Triple dimension array to a function * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); * Step 2 : Pass Address of Double dimension array to function ``fun`` .. code-block:: c fun(&tp[1]); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(char ***ptr) { } * Step 3.2 : Access and Print strings inside function ``fun`` .. code-block:: c void fun(char ***ptr) { for(int i = 0; i < 4; i++) { printf("%s", (*ptr)[i]); printf("\n"); } } * Step 3.3 : Access and Print characters inside function ``fun`` .. code-block:: c void fun(char ***ptr) { for(int i = 0; i < 4; i++) { for(int j = 0; j < 5; j++) { printf("%c", (*ptr)[i][j]); } printf("\n"); } } * Step 3.4 : Access and Change strings inside function ``fun`` .. code-block:: c void fun(char ***ptr) { for(int i = 0; i < 4; i++) { strncpy( (*ptr)[i], "gggg", 5); } } * Step 3.5 : Access and Change characters inside function ``fun`` .. code-block:: c void fun(char ***ptr) { for(int i = 0; i < 4; i++) { for(int j = 0; j < 5 - 1; j++) { (*ptr)[i][j] = 'c'; } } } * Step 4 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * Step 5 : See the full program below .. code-block:: c #include #include #include void fun(char ***ptr) { // Access Strings and Print printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", (*ptr)[i]); printf("\n"); } // Access Characters and Print printf("fun() : Access Characters and Print\n"); for(int i = 0; i < 4; i++) { for(int j = 0; j < 5; j++) { printf("%c", (*ptr)[i][j]); } printf("\n"); } //Access Strings and Change for(int i = 0; i < 4; i++) { strncpy((*ptr)[i], "gggg", 5); } printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", (*ptr)[i]); printf("\n"); } // Access Characters and Change for(int i = 0; i < 4; i++) { for(int j = 0; j < 5 - 1; j++) { (*ptr)[i][j] = 'c'; } } printf("fun() : Access Strings and Print\n"); for(int i = 0; i < 4; i++) { printf("%s", (*ptr)[i]); printf("\n"); } } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); fun(&tp[1]); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Step 5 : Output is as below .. code-block:: c fun() : Access Strings and Print gap0 pop0 yyy0 4560 fun() : Access Characters and Print gap0 pop0 yyy0 4560 fun() : Access Strings and Print gggg gggg gggg gggg fun() : Access Strings and Print cccc cccc cccc cccc .. _funcs_n_ptrs_char_tp_ex_21: .. tab-set:: .. tab-item:: Example 7 : Call by Reference : Pass Address of Triple Dimension array to a function * Step 1 : Consider a triple dimension array created using a character triple pointer .. code-block:: c char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); * Step 2 : Pass Address of Triple Dimension array to a function .. code-block:: c fun(&tp); * Step 3.1 : Define function ``fun`` .. code-block:: c void fun(char ****ptr ) { } * Step 3.2 : Access and Print the strings inside function ``fun`` .. 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 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 < 4; j++) { for(int k = 0; k < 4; k++) { printf("(*ptr)[%d][%d][%d] = %c\n", i, j, k, (*ptr)[i][j][k]); } } } * Step 3.4 : Access and change strings inside function ``fun`` .. code-block:: c for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) { strcpy( (*ptr)[i][j], "ccc"); } } * 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 < 4; j++) { for(int k = 0; k < 5; k++) { (*ptr)[i][j][k] = 'c'; } } } * Step 4 : Free memory after use .. code-block:: c for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); * See full program below .. code-block:: c #include #include #include void fun(char ****ptr) { //Access and print individual 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]); } } //Access and print individual characters for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) { for(int k = 0; k < 4; k++) { printf("(*ptr)[%d][%d][%d] = %c\n", i, j, k, (*ptr)[i][j][k]); } } } //Access and change individual strings for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) { strcpy( (*ptr)[i][j], "ccc"); } } //Access and change individual characters for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) { for(int k = 0; k < 5; k++) { (*ptr)[i][j][k] = 'c'; } } } } int main(void) { char ***tp; tp = malloc( 3 * sizeof(char **) ); for (int i = 0; i < 3; i++) { tp[i] = malloc( 4 * sizeof(sizeof(char *)) ); for (int j = 0; j < 4; j++) { tp[i][j] = malloc( 5 * sizeof(char) ); } } strcpy(tp[0][0], "lap0"); strcpy(tp[0][1], "top0"); strcpy(tp[0][2], "xxx0"); strcpy(tp[0][3], "1230"); strcpy(tp[1][0], "gap0"); strcpy(tp[1][1], "pop0"); strcpy(tp[1][2], "yyy0"); strcpy(tp[1][3], "4560"); strcpy(tp[2][0], "sap0"); strcpy(tp[2][1], "gop0"); strcpy(tp[2][2], "zzz0"); strcpy(tp[2][3], "7890"); fun(&tp); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { free( tp[i][j] ); } free( tp[i] ); } free(tp); return 0; } * Output is as below .. code-block:: c (*ptr)[0][0] = lap0 (*ptr)[0][1] = top0 (*ptr)[0][2] = xxx0 (*ptr)[0][3] = 1230 (*ptr)[1][0] = gap0 (*ptr)[1][1] = pop0 (*ptr)[1][2] = yyy0 (*ptr)[1][3] = 4560 (*ptr)[2][0] = sap0 (*ptr)[2][1] = gop0 (*ptr)[2][2] = zzz0 (*ptr)[2][3] = 7890 (*ptr)[0][0][0] = l (*ptr)[0][0][1] = a (*ptr)[0][0][2] = p (*ptr)[0][0][3] = 0 (*ptr)[0][1][0] = t (*ptr)[0][1][1] = o (*ptr)[0][1][2] = p (*ptr)[0][1][3] = 0 (*ptr)[0][2][0] = x (*ptr)[0][2][1] = x (*ptr)[0][2][2] = x (*ptr)[0][2][3] = 0 (*ptr)[0][3][0] = 1 (*ptr)[0][3][1] = 2 (*ptr)[0][3][2] = 3 (*ptr)[0][3][3] = 0 (*ptr)[1][0][0] = g (*ptr)[1][0][1] = a (*ptr)[1][0][2] = p (*ptr)[1][0][3] = 0 (*ptr)[1][1][0] = p (*ptr)[1][1][1] = o (*ptr)[1][1][2] = p (*ptr)[1][1][3] = 0 (*ptr)[1][2][0] = y (*ptr)[1][2][1] = y (*ptr)[1][2][2] = y (*ptr)[1][2][3] = 0 (*ptr)[1][3][0] = 4 (*ptr)[1][3][1] = 5 (*ptr)[1][3][2] = 6 (*ptr)[1][3][3] = 0 (*ptr)[2][0][0] = s (*ptr)[2][0][1] = a (*ptr)[2][0][2] = p (*ptr)[2][0][3] = 0 (*ptr)[2][1][0] = g (*ptr)[2][1][1] = o (*ptr)[2][1][2] = p (*ptr)[2][1][3] = 0 (*ptr)[2][2][0] = z (*ptr)[2][2][1] = z (*ptr)[2][2][2] = z (*ptr)[2][2][3] = 0 (*ptr)[2][3][0] = 7 (*ptr)[2][3][1] = 8 (*ptr)[2][3][2] = 9 (*ptr)[2][3][3] = 0 .. 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`