Functions and Integer Single 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 integer single 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_ints/int_sd_array` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Integer Single Dimension Array : Syntax ` * :ref:`Integer Single Dimension Array : FAQs ` * :ref:`Integer Single Dimension Array : 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 &a[ ] ` * :ref:`Example 4 : Call by Reference WITH (a + 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_int_sd_array_ex_0_0: .. tab-set:: .. tab-item:: Integer Single Dimension Array : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow int array_name[Column]; .. _funcs_n_ptrs_int_sd_array_ex_0_1: .. tab-set:: .. tab-item:: Integer Single Dimension Array : FAQs Consider a Integer Single Dimension Array .. code-block:: c int a[10]; .. 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_int_sd_array_ex_6: .. tab-set:: .. tab-item:: Integer Single 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]) void fun(int x) { } * Call by Value fun(a[1]) void fun(int x) { } * Call by Value fun(a[9]) void fun(int x) { } * Call by Value fun(&a[0]) void fun(int \*p) { } * Call by Reference fun(&a[1]) void fun(int \*p) { } * Call by Reference fun(&a[9]) void fun(int \*p) { } * Call by Reference fun(\*a) void fun(int x) { } * Call by Value fun(\*(a + 1)) void fun(int x) { } * Call by Value fun(\*(a + 9)) void fun(int x) { } * Call by Value fun(a) void fun(int \*p) { } * Call by Reference fun(a + 1) void fun(int \*p) { } * Call by Reference fun(a + 9) void fun(int \*p) { } * Call by Reference fun(&a) void fun(int (\*p) [10] ) { } * Call by Reference ================== =============================== ========================================================================== .. _funcs_n_ptrs_int_sd_array_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_int_sd_array_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 : &a[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 : a + 1, a + 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 : &a .. _funcs_n_ptrs_int_sd_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_int_sd_array_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 integer array ``a`` .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass an individual integer ``a[2]`` to a function. Call by Value .. code-block:: c fun(a[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 ``a[2]`` is third integer in the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``a[2]`` is fully dereferenced and there is no ``&`` symbol in ``fun(a[2])``. Hence this is Call By Value * Step 3 : Define function ``fun`` .. code-block:: c void fun(int x) { } * Step 4 : Change value of ``x`` inside function ``fun`` .. code-block:: c void fun(int x) { x = 100; printf("x = %d\n", x); } * See the full program below .. code-block:: c #include void fun(int x) { x = 300; printf("x = %d\n", x); } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; fun(a[2]); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } printf("\n"); return 0; } * Output is as below .. code-block:: c x = 300 a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``x`` inside function ``fun`` DOES NOT change ``a[2]`` in array ``a`` .. _funcs_n_ptrs_int_sd_array_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 integer array ``a`` .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass an individual integer ``*(a + 2)`` to a function. Call by Value .. code-block:: c fun( *(a + 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 ``*(a + 2)`` is third integer in the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``*(a + 2)`` is fully dereferenced and there is no ``&`` symbol in ``fun( *(a + 2) )``. Hence this is Call By Value * Step 3 : Define function ``fun`` .. code-block:: c void fun(int x) { } * Step 4 : Change value of ``x`` inside function ``fun`` .. code-block:: c void fun(int x) { x = 300; printf("x = %d\n", x); } * See the full program below .. code-block:: c #include void fun(int x) { x = 300; printf("x = %d\n", x); } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; fun( *(a + 2) ); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c x = 300 a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``x`` inside function ``fun`` DOES NOT change ``*(a + 2)`` in array ``a`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Remember ``a[2]`` and ``*(a + 2)`` are one and the same .. _funcs_n_ptrs_int_sd_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_int_sd_array_ex_9: .. tab-set:: .. tab-item:: Example 3 : Call by Reference WITH &a[ ] .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Reference with ``&a[ ]`` * Step 1 : Define a integer array ``a`` .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass address of an individual integer ``&a[2]`` to a function. Call by Reference .. code-block:: c fun( &a[2] ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Address of individual array elements can be accessed using ``&`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``&a[2]`` is the address of third integer in the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since we are passing address of third integer to function ``fun``, it is called call by reference with respect to third integer * Step 3 : Define function ``fun`` .. code-block:: c void fun(int *x) { } * Step 4 : Change value of ``*x`` inside function ``fun`` .. code-block:: c void fun(int *x) { *x = 300; printf("*x = %d\n", *x); } * See the full program below .. code-block:: c #include void fun(int *x) { *x = 300; printf("*x = %d\n", *x); } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; fun( &a[2] ); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c *x = 300 a[0] = 1 a[1] = 2 a[2] = 300 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``*x`` inside function ``fun`` CHANGES ``a[2]`` in array ``a`` .. _funcs_n_ptrs_int_sd_array_ex_10: .. tab-set:: .. tab-item:: Example 4 : Call by Reference WITH ``(a + x)`` .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Example for Call By Reference with ``(a + x)`` * Step 1 : Define a integer array ``a`` .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass address of individual integer ``a + 2`` to a function. Call by Reference .. code-block:: c fun( a + 2 ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow In this case ``a + 2`` is the address of third integer in the array .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since we are passing address of third integer to function ``fun``, it is called call by reference with respect to third integer * Step 3 : Define function ``fun`` .. code-block:: c void fun(int *x) { } * Step 4 : Change value of ``*x`` inside function ``fun`` .. code-block:: c void fun(int *x) { *x = 300; printf("*x = %d\n", *x); } * See the full program below .. code-block:: c #include void fun(int *x) { *x = 300; printf("*x = %d\n", *x); } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; fun( a + 2 ); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c *x = 300 a[0] = 1 a[1] = 2 a[2] = 300 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Changing value of ``*x`` inside function ``fun`` CHANGES ``a[2]`` in array ``a`` .. _funcs_n_ptrs_int_sd_array_ex_12: .. tab-set:: .. tab-item:: Example 5 : Pass full array array to a function * Step 1 : Consider a integer array .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass full array array to a function .. code-block:: c fun( a ); .. 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 3 : Define a function .. code-block:: c void fun(int *x) { x[0] = 100; x[1] = 200; x[2] = 300; x[3] = 400; x[4] = 500; x[5] = 600; x[6] = 700; x[7] = 800; x[8] = 900; x[9] = 1000; } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow function ``fun`` has access to all integers * See full program below .. code-block:: c #include void fun(int *x) { x[0] = 100; x[1] = 200; x[2] = 300; x[3] = 400; x[4] = 500; x[5] = 600; x[6] = 700; x[7] = 800; x[8] = 900; x[9] = 1000; } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; printf("----- Before call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } fun(a); printf("----- After call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c ----- Before call by reference ----- a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 ----- After call by reference ----- a[0] = 100 a[1] = 200 a[2] = 300 a[3] = 400 a[4] = 500 a[5] = 600 a[6] = 700 a[7] = 800 a[8] = 900 a[9] = 1000 .. _funcs_n_ptrs_int_sd_array_ex_13: .. tab-set:: .. tab-item:: Example 6 : Pass part of the array by reference * Step 1 : Consider a integer array .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass full array by reference .. code-block:: c fun( a + 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 integer .. 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 3 : Define a function .. code-block:: c void fun(int *x) { x[-5] = 100; // Same as a[0] x[-4] = 200; // Same as a[1] x[-3] = 300; // Same as a[2] x[-2] = 400; // Same as a[3] x[-1] = 500; // Same as a[4] x[0] = 600; // Same as a[5] x[1] = 700; // Same as a[6] x[2] = 800; // Same as a[7] x[3] = 900; // Same as a[8] x[4] = 1000; // Same as a[9] } .. 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 void fun(int *x) { x[-5] = 100; // Same as a[0] x[-4] = 200; // Same as a[1] x[-3] = 300; // Same as a[2] x[-2] = 400; // Same as a[3] x[-1] = 500; // Same as a[4] x[0] = 600; // Same as a[5] x[1] = 700; // Same as a[6] x[2] = 800; // Same as a[7] x[3] = 900; // Same as a[8] x[4] = 1000; // Same as a[9] } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; printf("----- Before call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } fun( a + 5 ); printf("----- After call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c ----- Before call by reference ----- a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 ----- After call by reference ----- a[0] = 100 a[1] = 200 a[2] = 300 a[3] = 400 a[4] = 500 a[5] = 600 a[6] = 700 a[7] = 800 a[8] = 900 a[9] = 1000 .. _funcs_n_ptrs_int_sd_array_ex_14: .. tab-set:: .. tab-item:: Example 7 : Address of full array and Pointer to an Array * Step 1 : Consider a integer array .. code-block:: c int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; * Step 2 : Pass the address of array ``a`` to function ``fun`` .. code-block:: c fun(&a); * Step 3 : Define the function ``fun`` .. code-block:: c void fun( int (*ptr)[10] ) { } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that ``int (*ptr)[10]`` is pointer to an array of 10 integers .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Which means incrementing ``ptr`` will increment by 10 Bytes and decrementing ``ptr`` will decrement by 10 Bytes * Step 4 : Access individual integers inside function ``fun`` .. code-block:: c void fun( int (*ptr)[10] ) { //Change individual integers (*ptr)[0] = 100; (*ptr)[1] = 200; (*ptr)[2] = 300; (*ptr)[3] = 400; (*ptr)[4] = 500; (*ptr)[5] = 600; (*ptr)[6] = 700; (*ptr)[7] = 800; (*ptr)[8] = 900; (*ptr)[9] = 1000; } * See the full program below .. code-block:: c #include void fun( int (*ptr)[10] ) { //Change individual integers (*ptr)[0] = 100; (*ptr)[1] = 200; (*ptr)[2] = 300; (*ptr)[3] = 400; (*ptr)[4] = 500; (*ptr)[5] = 600; (*ptr)[6] = 700; (*ptr)[7] = 800; (*ptr)[8] = 900; (*ptr)[9] = 1000; } int main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; printf("----- Before call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } fun( &a ); printf("----- After call by reference -----\n"); for (int i = 0; i < 10; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; } * Output is as below .. code-block:: c ----- Before call by reference ----- a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 a[5] = 6 a[6] = 7 a[7] = 8 a[8] = 9 a[9] = 10 ----- After call by reference ----- a[0] = 100 a[1] = 200 a[2] = 300 a[3] = 400 a[4] = 500 a[5] = 600 a[6] = 700 a[7] = 800 a[8] = 900 a[9] = 1000 .. card:: See Also * Other topics of integer and functions * :doc:`./int` * :doc:`./int_sd_array` * :doc:`./int_dd_array` * :doc:`./int_td_array` * :doc:`./int_sp` * :doc:`./int_dp` * :doc:`./int_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`