Functions and Character Single 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 single 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_sp` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Character Single Pointer : Syntax ` * :ref:`Character Single Pointer : FAQs ` * :ref:`Character Single Pointer : fun(expression) ` * :ref:`Rules for Call By Value ` * :ref:`Rules for Call By Reference ` * :ref:`Examples of Call by Value ` * :ref:`Example 1 : Call by Value with [ ] ` * :ref:`Example 2 : Call by Value with * ` * :ref:`Examples of Call by Reference ` * :ref:`Example 3 : Call by Reference WITH &sp[ ] ` * :ref:`Example 4 : Call by Reference WITH (sp + x) ` * :ref:`Example 5 : Pass full array to a function ` * :ref:`Example 6 : Pass part of the array by reference ` * :ref:`Example 7 : Address of full array and Pointer to an Array ` .. _funcs_n_ptrs_char_sp_ex_0_0: .. tab-set:: .. tab-item:: Character Single Pointer : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow char \*sp; .. _funcs_n_ptrs_char_sp_ex_0_1: .. tab-set:: .. tab-item:: Character Single Pointer : FAQs Consider a Character Single Pointer .. code-block:: c char *sp; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us answer few basic questions about character single pointer .. _funcs_n_ptrs_char_sp_ex_6: .. tab-set:: .. tab-item:: Character Single 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(sp[0]) void fun(char x) { } * Call by Value fun(sp[1]) void fun(char x) { } * Call by Value fun(sp[9]) void fun(char x) { } * Call by Value fun(&sp[0]) void fun(char \*p) { } * Call by Reference fun(&sp[1]) void fun(char \*p) { } * Call by Reference fun(&sp[9]) void fun(char \*p) { } * Call by Reference fun(\*sp) void fun(char x) { } * Call by Value fun(\*(sp + 1)) void fun(char x) { } * Call by Value fun(\*(sp + 9)) void fun(char x) { } * Call by Value fun(sp) void fun(char \*p) { } * Call by Reference fun(sp + 1) void fun(char \*p) { } * Call by Reference fun(sp + 9) void fun(char \*p) { } * Call by Reference fun(&sp) void fun(char \*\*p) { } * Call by Reference ================== =============================== ========================================================================== .. _funcs_n_ptrs_char_sp_rules_for_call_by_value: .. 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 ONE dereference operator, and * Expression has ONE dereference operator [], 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 ONE dereference operators, and * Expression has ONE dereference operator \*, and * Expression does not have ``&`` * then it is call by value .. _funcs_n_ptrs_char_sp_rules_for_call_by_reference: .. 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 ONE dereference operator, and * Expression has ONE dereference operators [] or \*, and * Expression has ONE & * then it is call by reference * Example : &sp[0] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has ONE dereference operator, and * Expression has ZERO dereference operator [ ] or \*, and * Expression has ZERO & operator * then it is call by reference * Example : sp + 1, sp + 4 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If Declaration has ONE dereference operator, and * Expression has ZERO dereference operator [ ] or \*, and * Expression has ONE & operator * then it is call by reference * Example : &sp .. _funcs_n_ptrs_char_sp_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_sp_ex_7: .. tab-set:: .. tab-item:: Example 1 : Call by Value with [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Value with [ ] * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass an individual character ``sp[2]`` to a function. Call by Value .. code-block:: c fun(sp[2]); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Individual heap elements can be accessed using [ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``sp[2]`` is third character in the heap .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``sp[2]`` is fully dereferenced and there is no ``&`` symbol in ``fun(sp[2])``. Hence this is Call By Value * Step 5 : Define function ``fun`` .. code-block:: c void fun(char x) { } * Step 6 : Change value of ``x`` inside function ``fun`` .. code-block:: c void fun(char x) { printf("x = %c\n", x); x = 'b'; } * Step 7 : Free heap memory after use .. code-block:: c free(sp); * See the full program below .. code-block:: c #include #include #include void fun(char x) { printf("x = %c\n", x); x = 'b'; } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun(sp[2]); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c x = p sp = Laptop123 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``x`` inside function ``fun`` DOES NOT change ``sp[2]`` .. _funcs_n_ptrs_char_sp_ex_8: .. tab-set:: .. tab-item:: Example 2 : Call by Value with ``*`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Value with ``*`` * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass an individual character ``*(a + 2)`` to a function. Call by Value .. code-block:: c fun( *(sp + 2) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Individual array elements can be accessed using ``*`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``*(sp + 2)`` is third character in the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``*(sp + 2)`` is fully dereferenced and there is no ``&`` symbol in ``fun( *(sp + 2) )``. Hence this is Call By Value * Step 5 : Define function ``fun`` .. code-block:: c void fun(char x) { } * Step 6 : Change value of ``x`` inside function ``fun`` .. code-block:: c void fun(char x) { printf("x = %c\n", x); x = 'b'; } * Step 7 : Free heap memory after use .. code-block:: c free(sp); * See the full program below .. code-block:: c #include #include #include void fun(char x) { printf("x = %c\n", x); x = 'b'; } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun( *(sp + 2) ); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c x = p sp = Laptop123 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``x`` inside function ``fun`` DOES NOT change ``*(sp + 2)`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Remember ``sp[2]`` and ``*(sp + 2)`` are one and the same .. _funcs_n_ptrs_char_sp_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_sp_ex_9: .. tab-set:: .. tab-item:: Example 3 : Call by Reference WITH &sp[ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Reference with ``&sp[ ]`` * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass address of an individual character ``&sp[2]`` to a function. Call by Reference .. code-block:: c fun( &sp[2] ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Address of individual heap elements can be accessed using ``&`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``&sp[2]`` is the address of third character in the heap .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since we are passing address of third character to function ``fun``, it is called call by reference with respect to third character * Step 5 : Define function ``fun`` .. code-block:: c void fun(char *x) { } * Step 6 : Change value of ``*x`` inside function ``fun`` .. code-block:: c void fun(char *x) { printf("*x = %c\n", *x); *x = 'b'; } * Step 7 : Free heap memory after use .. code-block:: c free(sp); * See the full program below .. code-block:: c #include #include #include void fun(char *x) { printf("*x = %c\n", *x); *x = 'b'; } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun( &sp[2] ); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c *x = p sp = Labtop123 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``*x`` inside function ``fun`` CHANGES ``sp[2]`` in ``sp`` .. _funcs_n_ptrs_char_sp_ex_10: .. tab-set:: .. tab-item:: Example 4 : Call by Reference WITH ``(sp + x)`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Reference with ``(sp + x)`` * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass address of individual character ``sp + 2`` to a function. Call by Reference .. code-block:: c fun( sp + 2 ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``sp + 2`` is the address of third character in the heap .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since we are passing address of third character to function ``fun``, it is called call by reference with respect to third character * Step 5 : Define function ``fun`` .. code-block:: c void fun(char *x) { } * Step 6 : Change value of ``*x`` inside function ``fun`` .. code-block:: c void fun(char *x) { printf("*x = %c\n", *x); *x = 'b'; } * Step 7 : Free heap memory after use .. code-block:: c free(sp); * See the full program below .. code-block:: c #include #include #include void fun(char *x) { printf("*x = %c\n", *x); *x = 'b'; } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun( sp + 2 ); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c *x = p sp = Labtop123 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``*x`` inside function ``fun`` CHANGES ``sp[2]`` .. _funcs_n_ptrs_char_sp_ex_12: .. tab-set:: .. tab-item:: Example 5 : Pass full array to a function * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass full array array to a function .. code-block:: c fun( sp ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that we are passing starting address of array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence function ``fun`` has read and write access to all Bytes of array * Step 5 : Define a function .. code-block:: c void fun(char *x) { printf("x = %s\n", x); strcpy(x, "Laptop456"); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow function ``fun`` has access to all characters * Step 6 : Free heap memory after use .. code-block:: c free(sp); * See full program below .. code-block:: c #include #include #include void fun(char *x) { printf("x = %s\n", x); strcpy(x, "Laptop456"); } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun(sp); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c x = Laptop123 sp = Laptop456 .. _funcs_n_ptrs_char_sp_ex_13: .. tab-set:: .. tab-item:: Example 6 : Pass part of the array by reference * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass full array by reference with relative addressing .. code-block:: c fun( sp + 5 ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that we are passing part of the array by reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case, we are passing address of 6th character .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence function ``fun`` has read and write access to Bytes 5, 6, 7, 8, 9 in forward direction .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Hence function ``fun`` has read and write access to Bytes 0, 1, 2, 3, 4 in backward direction * Step 5 : Define a function .. code-block:: c void fun(char *x) { printf("x = %s\n", x); x[-5] = 'b'; // Same as a[0] x[-4] = 'a'; // Same as a[1] x[-3] = 'p'; // Same as a[2] x[-2] = 't'; // Same as a[3] x[-1] = 'a'; // Same as a[4] x[0] = 'p'; // Same as a[5] x[1] = '4'; // Same as a[6] x[2] = '5'; // Same as a[7] x[3] = '6'; // Same as a[8] } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note the relative access mechanism used inside function ``fun`` * See full program below .. code-block:: c #include #include #include void fun(char *x) { printf("x = %s\n", x); x[-5] = 'b'; // Same as a[0] x[-4] = 'a'; // Same as a[1] x[-3] = 'p'; // Same as a[2] x[-2] = 't'; // Same as a[3] x[-1] = 'a'; // Same as a[4] x[0] = 'p'; // Same as a[5] x[1] = '4'; // Same as a[6] x[2] = '5'; // Same as a[7] x[3] = '6'; // Same as a[8] } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun(sp + 5); printf("sp = %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c x = p123 sp = baptap456 .. _funcs_n_ptrs_char_sp_ex_14: .. tab-set:: .. tab-item:: Example 7 : Pass address of character single pointer to a function * Step 1 : Define a character single pointer ``sp`` .. code-block:: c char *sp; * Step 2 : Allocate heap memory of Bytes .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy string to heap memory pointed to by ``sp`` .. code-block:: c strcpy(sp, "Laptop123"); * Step 4 : Pass the address of array ``sp`` to function ``fun`` .. code-block:: c fun(&sp); * Step 5 : Define the function ``fun`` .. code-block:: c void fun( char **dp) { } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that ``char **dp`` is a pointer to a character single pointer * Step 6 : Access full string inside function ``fun`` .. code-block:: c void fun( char **dp ) { printf("fun : String is %s\n", *dp); // Change full string strcpy(*dp, "Laptop456"); } * Step 7 : Access individual characters inside function ``fun`` .. code-block:: c void fun( char **dp ) { //Change individual characters (*dp)[0] = 'g'; (*dp)[1] = 'a'; (*dp)[2] = 'p'; (*dp)[3] = 't'; (*dp)[4] = 'a'; (*dp)[5] = 'p'; (*dp)[6] = '4'; (*dp)[7] = '5'; (*dp)[8] = '6'; (*dp)[9] = '\0'; } * Step 8 : Free heap memory after use .. code-block:: c free(sp); * See the full program below .. code-block:: c #include #include #include void fun( char **dp ) { //Change individual characters (*dp)[0] = 'g'; (*dp)[1] = 'a'; (*dp)[2] = 'p'; (*dp)[3] = 't'; (*dp)[4] = 'a'; (*dp)[5] = 'p'; (*dp)[6] = '4'; (*dp)[7] = '5'; (*dp)[8] = '6'; (*dp)[9] = '\0'; } int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop123"); fun(&sp); printf("main : String is %s\n", sp); free(sp); return 0; } * Output is as below .. code-block:: c main : String is gaptap456 .. 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`