Functions and Structure ============================ In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow What are the basic properties of a structure ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow What is Call by Value ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow What is Call by Reference ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Structure : Syntax ` * :ref:`Structure : FAQs ` * :ref:`Structure : Basic Properties ` * :ref:`Structure : Call by Value ` * :ref:`Structure : Call by Reference ` * :ref:`Summary ` .. _funcs_n_ptrs_struct_ex_0_0: .. tab-set:: .. tab-item:: Structure : Syntax .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow .. code-block:: c struct ABC { type1 member1; type2 member2; type3 member3; }; struct ABC x; .. _funcs_n_ptrs_struct_ex_0_1: .. tab-set:: .. tab-item:: Structure : FAQs Consider a Structure .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC x; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us answer few basic questions about a Structure .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How many structures can be stored in ``x`` ? .. dropdown:: See Answer Number of Structures = 1 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How many bytes are there in this Structure ? .. dropdown:: See Answer Number of Bytes = 12 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow What is the sizeof the Structure ? .. dropdown:: See Answer sizeof(a) = Number of Bytes = 12 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How many bits are there in this Structure ? .. dropdown:: See Answer Number of bits = sizeof(x) * 8 = 12 * 8 = 96 bits .. _funcs_n_ptrs_struct_ex_1: .. tab-set:: .. tab-item:: Structure : Basic Properties Consider a structure .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC x; Then below are the properties of a structure =================== ======================================== Expression ? =================== ======================================== x ``x`` is a structure &x ``&x`` is address of structure ``x`` \*x NOT VALID sizeof(x) 12 Bytes sizeof(&x) 8 Bytes typeof(x) ``struct ABC`` typeof(&x) ``struct ABC *`` =================== ======================================== .. _funcs_n_ptrs_struct_ex_2: .. tab-set:: .. tab-item:: Structure : Call by Value .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Structure passed to a function * Step 1 : Define a structure .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC x; * Step 2 : Pass structure to a function .. code-block:: c fun(x); * Step 3 : Define a function ``fun`` .. code-block:: c void fun(struct ABC x) { } * Step 4 : Change structure inside function ``fun`` .. code-block:: c void fun(struct ABC x) { x.a = 10; x.b = 20; x.c = 30; } * See full program below .. code-block:: c #include struct ABC { int a; int b; int c; }; void fun(struct ABC x) { x.a = 10; x.b = 20; x.c = 30; } int main(void) { struct ABC x = {.a = 1, .b = 2, .c = 3}; printf("----- Before Call By Value -----\n"); printf("x.a = %d, x.b = %d, x.c = %d\n", x.a, x.b, x.c); fun(x); printf("----- Before Call By Value -----\n"); printf("x.a = %d, x.b = %d, x.c = %d\n", x.a, x.b, x.c); return 0; } * Output is as below .. code-block:: c ----- Before Call By Value ----- x.a = 1, x.b = 2, x.c = 3 ----- Before Call By Value ----- x.a = 1, x.b = 2, x.c = 3 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Can you guess what is happening ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow After function ``fun`` is called, * There are two stack frames * Stack frame of ``main`` * Stack frame of ``fun`` * variable ``c`` is created on stack frame of ``main`` * variable ``c`` is created on stack frame of ``fun`` * Even though name of variable ``c`` is same in ``main`` and ``fun``, they are two different variables in memory * Hence changing value of ``c`` inside function ``fun`` does not change the value of ``c`` inside ``main`` .. _funcs_n_ptrs_struct_ex_3: .. tab-set:: .. tab-item:: Structure : Call by Reference .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Address of Structure passed to a function * Step 1 : Define a structure .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC x; * Step 2 : Pass address of structure to a function .. code-block:: c fun(&x); * Step 3 : Define a function ``fun`` .. code-block:: c void fun(struct ABC *p) { } * Step 4 : Change structure inside function ``fun`` .. code-block:: c void fun(struct ABC *p) { p->a = 10; p->b = 20; p->c = 30; } * See full program below .. code-block:: c #include struct ABC { int a; int b; int c; }; void fun(struct ABC *p) { p->a = 10; p->b = 20; p->c = 30; } int main(void) { struct ABC x = {.a = 1, .b = 2, .c = 3}; printf("----- Before Call By Reference -----\n"); printf("x.a = %d, x.b = %d, x.c = %d\n", x.a, x.b, x.c); fun(&x); printf("----- After Call By Reference -----\n"); printf("x.a = %d, x.b = %d, x.c = %d\n", x.a, x.b, x.c); return 0; } * Output is as below .. code-block:: c ----- Before Call By Reference ----- x.a = 1, x.b = 2, x.c = 3 ----- After Call By Reference ----- x.a = 10, x.b = 20, x.c = 30 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Can you guess what is happening ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Let us solve it with equations method ! * Rule 1 : Base Rule .. code-block:: c p = &x .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * RHS is actual parameter. In this case ``&x`` is actual parameter * LHS is formal parameter. In this case ``p`` is formal parameter * Rule 2 : Move ``&`` from RHS to LHS. This becomes ``*`` on LHS .. code-block:: c *p = x * Rule 3 : Changing ``*p`` also changes ``x``. Because we proved ``*p`` is equal to ``x`` .. _funcs_n_ptrs_struct_ex_4: .. tab-set:: .. tab-item:: Summary ================================ =============================== ========================================================================== Function Call Function Definition Observations ================================ =============================== ========================================================================== fun(x) void fun(struct ABC x) { } Changing ``x`` inside ``fun`` DOES NOT change value of ``x`` in caller fun(&x) void fun(struct ABC \*p) { } Changing ``*p`` inside ``fun`` CHANGES value of ``x`` in caller ================================ =============================== ========================================================================== .. card:: See Also * Other topics of structure and functions * :doc:`./struct` * :doc:`./struct_sd_array` * :doc:`./struct_dd_array` * :doc:`./struct_td_array` * :doc:`./struct_sp` * :doc:`./struct_dp` * :doc:`./struct_tp` * Current Module * :doc:`../funcs_n_ptrs` * Previous Module * :doc:`../../typecasting_n_ptr/typecasting_n_ptr` * Next Module * :doc:`../../memcpy_ptr/memcpy_ptr` * Other Modules * :doc:`../../variable_and_ptr/variable_and_ptr` * :doc:`../../array_n_ptrs/array_n_ptrs` * :doc:`../../malloc_ptr/malloc_ptr` * :doc:`../../const_ptr/const_ptr` * :doc:`../../void_ptr/void_ptr` * :doc:`../../array_of_ptr/array_of_ptr` * :doc:`../../ptr_to_array/ptr_to_array` * :doc:`../../function_ptr/function_ptr` * :doc:`../../pre_incr_ptr/pre_incr_ptr` * :doc:`../../post_incr_ptr/post_incr_ptr` * :doc:`../../pre_decr_ptr/pre_decr_ptr` * :doc:`../../post_decr_ptr/post_decr_ptr`