User Defined Function in C programming

 


  

Introduction

Functions are a set of statements that are combined to perform a specific task.

Ø  user-defined function is a type of function in C language that is defined by the user himself to perform some specific task.

Ø  It provides code reusability and modularity to our program. 

Ø  User-defined functions are different from built-in functions as their working is specified by the user and no header file is required for their usage.

Ø  Syntax

return_type function_name (type1 arg1, type2 arg2 .... typeN argN) {

    // actual statements to be executed

    // return value if any

}

Benefits of User-Defined Functions

Ø  Reusability: One of the main benefits of user-defined functions is that they can be reused in different parts of a program. Instead of writing the same code multiple times, you can define a function and call it whenever you need to perform a specific task.

Ø  Modularity: User-defined functions promote modularity in a program by breaking it down into smaller, manageable parts. It makes it easier to understand the code and debug any issues that may arise.

Ø  Simplified code: User-defined functions can simplify the code by abstracting away complex logic into a single function. It makes the code easier to read and understand.

Ø  Better testing: By breaking down a program into smaller functions, it becomes easier to test each function individually. It makes it easier to identify and isolate issues within the code, making it easier to fix any bugs and improve the overall quality of the program.

Components

Ø  There are three components of the function definition:

Ø  Function Parameters

Ø  Function Body

Ø  Return Value

Ø  Function Parameters

Ø  Function parameters (also known as arguments) are the values that are passed to the called function by the caller.

Ø  We can pass none or any number of function parameters to the function.

Ø  We have to define the function name and its type in the function definition and we can only pass the same number and type of parameters in the function call.

Ø  Example:

Ø  int name(int a, int b);

Ø  Here, a and b are function parameters.

Ø  Function Body

Ø  The function body is the set of statements that are enclosed within { } braces.

Ø  They are the statements that are executed when the function is called.

Ø  Example:

int name(int a, int b) {

    int sum = a + b;

    return sum;

}

Here, the statements between { and } is function body.

Ø  Return Value

Ø  The return value is the value returned by the function to its caller.

Ø  A function can only return a single value and it is optional.

Ø  If no value is to be returned, the return type is defined as void.

Ø  The return keyword is used to return the value from a function.

Ø  Syntax

Ø  return (expression);

Ø  Example

int name(int a, int b) {

    return a + b;

}

Library Function vs. Users Defined Function

How to use User-Defined Functions in C?

Ø  To use a user-defined function, we first have to understand the different parts of its syntax.

Ø  The user-defined function in C can be divided into three parts:

Ø  Function Prototype

Ø  Function Definition

Ø  Function Call

Function Prototype

Ø  A function prototype is also known as a function declaration which specifies the function’s name, function parameters, and return type.

Ø  The function prototype does not contain the body of the function.  

Ø  It is basically used to inform the compiler about the existence of the user-defined function which can be used in the later part of the program.

Ø  Syntax

Ø  return_type function_name (type1 arg1, type2 arg2, ... typeN argN);

Ø  We can also skip the name of the arguments in the function prototype. So,

Ø  return_type function_name (type1 , type2 , ... typeN);

Function Definition

Ø  Once the function has been called, the function definition contains the actual statements that will be executed.

Ø  All the statements of the function definition are enclosed within { } braces.

Ø  Syntax

return_type function_name (type1 arg1, type2 arg2 .... typeN argN) {

// actual statements to be executed

// return value if any

}

Ø  Note: If the function call is present after the function definition, we can skip the function prototype part and directly define the function.

Function Call

Ø  In order to transfer control to a user-defined function, we need to call it.

Ø  Functions are called using their names followed by round brackets.

Ø  Their arguments are passed inside the brackets.

Ø  Syntax

Ø  function_name(arg1, arg2, ... argN);

Program to illustrate the function call

            #include<stdio.h>

            int sum(int,int);        //Funtion Prototype

            //function Defination

            int sum(int a,int b) {

               return (a+b);

            }

            void main() {

                 int x=5,y=6;

                 int total;

                 total = sum(x,y);   //function call

                 printf("The sum of x and y is: %d",total);

            }

Function Parameters

Ø  When we call a function in main() or anywhere else in the program, and the function we created needs parameters, we would pass parameters to it while calling the function.

Ø  In the previous example, we passed variables x and y to obtain the sum of x and y.

Ø  According to the example above, the formal parameters are a and b, and the actual parameters are x and y.

Ø  Essentially, the variables being passed in the function call are actual parameters, and the variables being initialized and used in the function are formal parameters.

Different Forms of Function

Ø  The user-defined functions are further divided into four types on the basis of arguments and return value processing:

Ø  Functions with arguments and return values.

Ø  Functions with arguments and without return values.

Ø  Functions without arguments and with return values.

Ø  Functions without arguments and without return values.

             

Functions with arguments and return values

            #include <stdio.h>

            int sub(int,int);

            void main() {

              int x=10,y=7;

              int res = sub(x,y);

              printf("x-y = %d",res);

            }

            int sub(int a,int b) {

              int c = a - b;

              return c;

            }

            Functions with arguments and without return values

            #include <stdio.h>

            void sub(int,int);

            void main() {

              int x=10,y=7;

              sub(x,y);

            }

            void sub(int a,int b) {

              int c = a-b;

               printf("x-y = %d",c);

            }

            Functions without arguments and with return values

            #include <stdio.h>

            int sub();

            void main() {

              int res = sub();

              printf("a-b = %d",res);

            }

            int sub() {

              int a = 10, b = 7;

              int c = a - b;

              return c;

            }

            Functions without arguments and without return values

            #include <stdio.h>

            void sub();

            void main()  {

              sub();

            }

            void sub()  {

              int a = 10, b = 7;

              int c;

              c = a - b;

              printf("The difference of a and b is %d.",c);

            }

            Recursion



            The process in which a function calls itself directly or indirectly is called recursion.

            The corresponding function is called a recursive function.

            Using a recursive algorithm, certain problems can be solved quite easily. Examples of such problems are

            Fibonacci Series, factorial, reversing an integer, checking prime number, etc.

            we should provide a certain case in order to terminate this recursion process

Principle of Recursion

Ø  A recursive function has two different parts.

Ø   The base case and the recursive case.

Ø  The base case is used to terminate the task of recurring. If base case is not defined, then the function will recur infinite number of times

Ø  In computer program, when we call one function, the value of the program counter is stored into the internal stack before jumping into the function area.

Ø  After completing the task, it pops out the address and assign it into the program counter, then resume the task.

Ø  During recursive call, it will store the address multiple times, and jumps into the next function call statement.

Ø  If one base case is not defined, it will recur again and again, and store address into stack. If the stack has no space anymore, it will raise an error as “Internal Stack Overflow”.

Example

Ø  One example of recursive call is finding the factorial of a number.

Ø  We can see that the factorial of a number n = n! is same as the n * (n-1)!, again it is same as n * (n - 1) * (n - 2)!.

Ø  So if the factorial is a function, then it will be called again and again, but the argument is decreased by 1.

Ø  When the argument is 1 or 0, it will return 1. This could be the base case of the recursion.

int fact(int n)

{

    if (n < = 1) // base case

        return 1;

   else   

       return n*fact(n-1);   

}

WAP to find the Fibonacci series using recursion

            #include<stdio.h>

            int fibonacci(int);

            int main(){

                int n, i;

                printf("Enter the number of element you want in series :");

                scanf("%d",&n);

                printf("fibonacci series is : \n");

      for(i=0;i<n;i++)  {

                          printf("%d \n",fibonacci(i));

                }

             return 0;

            }

            int fibonacci(int n)  {

                    if(n==0)

                          return 0;

                    else if(n==1)

                             return 1;

                   else

                         return (fibonacci(n-1)+fibonacci(n-2));

            }

            WAP to find the reverse of an integer.

            int revNumFunction(int num){

               if(num){

                  rem=num%10;

                  sum=sum*10+rem;

                  revNumFunction(num/10);

               }

               else

                  return sum;

            }

            Passing Array to Function

            In C programming, you can pass an entire array to functions.

            Passing array elements to a function is similar to passing variables to a function.

            we need to pass only the name of the array in the function which is intended to accept an array.

            The array defined as the formal parameter will automatically refer to the array specified by the array name defined as an actual parameter.

            Syntax:

            Function_name(array_name);          //passing array  

 

 WAP to find the sum of an element in array and display the element in an array using function.

            #include <stdio.h>

            float calculateSum(float num[]);

            void display(float []);

            int main() {

              float result, num[] = {23.4, 55, 22.6, 3, 40.5, 18};

              printf("The elements in array are: ");

              display(num);

              result = calculateSum(num);

              printf("\nSum = %.2f", result);

              return 0;

            }

            float calculateSum(float num[]) {

                int i;

              float sum = 0.0;

              for (i=0;i<6;++i) {

                sum += num[i];

              }

              return sum;

            }

            void display(float num[])  {

                int i;

                for(i=0;i<6;i++){

                    printf("%.2f ",num[i]);

                }

            }

            Passing String to Function

            We know that strings are saved in arrays so, to pass an one dimensional array to a function we will have the following declaration.

            Syntax:

            returnType functionName(char str[]);

            Example:

            void displayString(char str[]);

            In the above example we have a function by the name displayString and it takes an argument of type char and the argument is an one dimensional array as we are using the [] square brackets.

            Passing one dimensional string to a function

            To pass a one dimensional string to a function as an argument we just write the name of the string array variable.

            In the following example we have a string array variable message and it is passed to the displayString function. Example:

            #include <stdio.h>

            void displayString(char []);

            int main() {

              char message[] = "Hello World";

              displayString(message);

              return 0;

            }

            void displayString(char str[])   {

                printf("String: %s\n", str);

            }

            Another way we can print the string is by using a loop like for or while and print characters till we hit the NULL character.

            In the following example we have redefined the displayString function logic.

            #include <stdio.h>

            void displayString(char []);

            int main(void) {

              char message[] = "Hello World";

              displayString(message);

              return 0;

            }

            void displayString(char str[]) {

              int i = 0;

              printf("String: ");

              while (str[i] != '\0') {

                printf("%c", str[i]);

                i++;

              }

            }

            Function declaration to accept two dimensional string

            In order to accept two dimensional string array the function declaration will look like the following.

            Syntax:

            returnType functionName(char [][C], type rows);

            Example:

            void displayCities(char str[][50], int rows);

            In the above example we have a function by the name displayCities and it takes a two dimensional string array of type char.

            The str is a two dimensional array as because we are using two [][] sqaure brackets.

            It is important to specify the second dimension of the array and in this example the second dimension i.e., total number of columns is 50.

            The second parameter rows tell us about the total number of rows in the given two dimensional string array str.

            Passing two dimensional string to a function

            #include <stdio.h>

            void displayCities(char [][50], int rows);

            int main(void) {   

              char cities[][50] = {"Bangalore","Chennai","Kolkata","Mumbai","New Delhi" };

                int rows = 5;

              displayCities(cities, rows);

              return 0;

            }

            void displayCities(char str[][50], int rows)  {

              int r, i;

              printf("Cities:\n");

              for (r = 0; r < rows; r++) {

                i = 0;

                while(str[r][i] != '\0') {

                  printf("%c", str[r][i]);

                  i++;

                }

                printf("\n");

              }

            }

            Accessing a function (Function calling)

            A function call is an important part of the C programming language.

            It is called inside a program whenever it is required to call a function.

            It is only called by its name in the main() function of a program.

            We can pass the parameters to a function calling in the main() function.

            There are two different methods of calling a function in the C programming language:

            Call by value

            In this method, we will be calling a function by value.

            we send a copy of the actual variable to the function while calling it.

            Because of this, any change in the value of this variable inside the body of the function is not reflected outside.

            When single or multiple values of an actual argument are copied into the formal parameter of a function, the method is called the Call by Value.

            Hence, it does not alter the function's actual parameter using the formal parameter.

            WAP to simulate the function call by value.

            #include <stdio.h> 

            Void main() { 

                int x = 10, y = 20; 

                printf (" x = %d, y = %d from main before calling the function", x, y); 

                 newValue(x, y); 

                 printf( "\n x = %d, y = %d from main after calling the function", x, y); 

            }

            void newValue( int x, int y) { 

                  x = x + 3; 

                  y = y + 5; 

                  printf (" \nx = %d, y = %d from function", x, y); 

            }

             

             

            Call by reference

            In this method, the address of the actual argument is copied into the function call's formal parameter; the method is known as Call by Reference.

            If we make some changes in the formal parameters, it shows the effect in the value of the actual parameter.

            we send a reference of the actual variable to the function while calling it which is why any change in the value of this variable inside the body of the function is also reflected outside.

            WAP to simulate the function call by reference.

            #include <stdio.h> 

            void main() { 

            int x = 10, y = 20; 

            printf (" x = %d, y = %d from main before calling the function", x, y); 

            newValue (&x, &y); 

            printf( "\n x = %d, y = %d from main after calling the function", x, y); 

           

            void newValue( int *a, int *b) { 

            *a = *a + 5; 

            *b = *b + 5; 

            printf (" \nx = %d, y = %d from function", *a, *b); 

            }

            Macros

Ø  macro is a piece of code in a program that is replaced by the value of the macro.

Ø  Macro is defined by #define directive.

Ø  Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro.

Ø  Macro definitions need not be terminated by a semi-colon(;).

Ø  Types Of Macros 

Ø  Object-like Macros

Ø  Chain Macros

Ø  Multi-line Macros

Ø  Function-like Macro

Object-like Macros

Ø  An object-like macro is a simple identifier that will be replaced by a code fragment.

Ø  It is called object-like because it looks like an object in code that uses it.

Ø  It is popularly used to replace a symbolic name with numerical/variable represented as constant.

#include <stdio.h>

#define PI 3.14

int main()

{

    printf("The value of the PI is %.2f", PI);

    return 0;

}

Chain Macros

Ø  Macros inside macros are termed as chain macros.

Ø  In chain macros first of all parent macro is expanded then the child macro is expanded. 

#include <stdio.h>

// Macro definition

#define INSTAGRAM FOLLOWERS

#define FOLLOWERS 138

int main()

{

   printf(“Our college have %dK followers on Instagram", INSTAGRAM);

   return 0;

}

Multi-line Macros

Ø  An object-like macro could have a multi-line.

Ø  So to create a multi-line macro you have to use backslash-newline. 

#include <stdio.h>

// Multi-line Macro definition

#define ELE 1, \

           2, \

            3

void main() {

    int arr[] = { ELE };

    printf("Elements of Array are:\n");

    for (int i = 0; i < 3; i++) {

        printf("%d  ", arr[i]);

    }

}

Function-like Macro

Ø  These macros are the same as a function call. It replaces the entire code instead of a function name.

Ø  Pair of parentheses immediately after the macro name is necessary.

Ø  If we put a space between the macro name and the parentheses in the macro definition, then the macro will not work

Ø  A function-like macro is only lengthened if and only if its name appears with a pair of parentheses after it.

Ø  If we don’t do this, the function pointer will get the address of the real function and lead to a syntax error.

#include <stdio.h>

// Function-like Macro definition

#define min(a, b) (((a) < (b)) ? (a) : (b))

int main() {

    int a = 18;

    int b = 76;

    printf("Minimum value between %d and %d is %d\n",a, b, min(a, b));

   return 0;

}

WAP to find the area of a circle by defining AREA(r) Macros. 

            #include <stdio.h>

            #define  PI  3.1416

            #define  AREA(r)  (PI*(r)*(r))

            int main() {

                float r = 7;    // radius of circle

                   

                printf("Area of Circle with radius %f: %.3f", r, AREA(r));

                return 0;

            }

Advantages of Macros

Ø  Increased productivity:

Ø  Macros can save time and reduce errors by automating repetitive tasks.

Ø  Customization: 

Ø  Macros can be customized to fit specific needs, allowing for greater flexibility in how tasks are completed.

Ø  Consistency: 

Ø  Macros can help ensure consistency in tasks by following a set of predetermined instructions.

Ø  Efficiency: 

Ø  Macros can perform tasks more quickly than humans, improving overall efficiency.

Ø  Ease of use: 

Ø  Macros are easy to create and use, requiring little to no programming knowledge

Disadvantages of Macros

Ø  Security risks: 

Ø  Macros can be a security risk if they are not properly secured or if they are used to execute malicious code.

Ø  Limited functionality: 

Ø  Macros may not be able to perform more complex tasks, limiting their usefulness.

Ø  Compatibility issues: 

Ø  Macros may not be compatible with all software applications, limiting their usefulness.

Ø  Maintenance: 

Ø  Macros may require maintenance and updates, which can be time-consuming and costly.

Ø  Dependence: 

Ø  Over-reliance on macros can result in decreased problem-solving skills and critical thinking.

Storage Class

Ø  We use the storage class in the C language for determining the visibility, lifetime, initial value, and memory location of any given variable.

Ø  The storage classes define the visibility (scope) and the lifetime of any function/ variable within a C program, which help us to trace the existence of a particular variable during the runtime of a program.

Ø  These classes precede the type that they are going to modify.

Ø  Types of Storage Classes in C

Ø  Automatic Storage Class

Ø  External Storage Class

Ø  Static Storage Class

Ø  Register Storage Class

Summary of Storage Classes in C


Automatic Storage Class

Ø  It is also known as the auto storage class, and it acts as the default storage class for all the variables that are local in nature.

            Features of automatic variables:

Ø  The allocation of memory for these variables occurs automatically during the runtime.

Ø  The scope of an automatic variable is limited to that block in which we are defining them.

Ø  The visibility of these variables is also limited to that block in which we are defining them.

Ø  The initialization of these variables is, by default, a garbage value.

Ø  The memory that is assigned to an automatic variable gets free when it exits from a block.

Ø  We use the keyword auto to define the automatic variables.

Ø  Any local variable that exists in the C language is, by default, automatic in nature.

Automatic Storage Class (Example)

            #include <stdio.h>

            int main()  {

                int p; //auto

                char q;

                float r;

                printf(“%d %c %f”,p,q,r); // to print the initial default value of the automatic variables p, q, and r.

                return 0;

            }

            #include <stdio.h>

            int main() {

               int p = 10,i;

               printf("%d ",++p);

               {

                    int p = 20;

                    for (i=0;i<3;i++) {

                          printf("%d ",p); // 20 will be printed here 3 times because it is the given local value of p

                     }

                 }

                  printf("%d ",p); // 11 will be printed here since the scope of p = 20 has finally ended.

            }

External Storage Class

Ø  It is also known as the extern storage class, and we use it for giving a reference of any global variable which is visible to all the files present in a program.

Ø  When using the extern storage class, we cannot initialize the variable.

Ø  However, note that it points to the name of the variable at any storage location that we have already defined (previously).

Ø  Whenever we have multiple numbers of files while we are trying to define any global variable or a function (that will be used in various other files too), then we will use the extern in another file for providing the reference of the defined function or variable.

Ø  In simpler words, we use the extern for declaring a function or a global variable in another file.

Features External Storage Class

Ø  We use the external storage class for conveying to the compiler that the variable that has been defined as the extern has been declared using an external linkage that exists elsewhere in any program.

Ø  One can only perform the initialization of an external variable globally. In other words, one cannot perform the initialization of an external variable within any given method or block.

Ø  The variables that are declared as extern have no allocation of memory. It only has a declaration, and it intends to specify that the given variable has been declared elsewhere in the available program.

Ø  An external integral type’s default initial value is going to be 0, or else it is null.

Ø  We can initialize an external variable multiple times, but we can only initialize it a single time.

Ø  When we declare a variable as external, the compiler will start searching for that variable for initialization somewhere in the available program. It might be static or extern. In case it isn’t, the compiler will ultimately generate an error (a compile-time error).

External Storage Class (Example)

            #include <stdio.h>

            int a;

            int main() {

                  extern int a; // variable a is defined globally, the memory will not be allocated to a

                  printf(“%d”,a);

            }

            #include <stdio.h>

            int main()  {

                extern int x; // The compiler will start searching here if a variable x has been defined and initialized in the program somewhere or not.

                printf(“%d”,x);

            }

            int x = 20;

            extern int x;

            int x = 10;

            #include <stdio.h>

            int main() {

                  printf(“%d”,x);

            }

            int x = 20; // the compiler will generate an error at this line in the output

Static Storage Class

Ø  This type of storage class gives an instruction to a compiler to keep the given local variable around during the program’s lifetime- instead of creating it and then destroying it every time it comes into a scope and goes out of it.

Ø  Thus, when we make a local variable static, it allows the variable to maintain the values that are available between various function calls.

Ø  We may also apply a static modifier to a global variable.

Ø  When we do so, it will cause the scope of the variable to be restricted to that file in which its declaration happened.

Ø  In a C programming language, when we use the static on a global variable, it will cause all the objects present in a class to share a single copy of that given member.

Features of Static Storage Class

Ø  Those variables that we define as static specifiers are capable of holding their assigned value that exists between various function calls.

Ø  The static local variables are only visible to the block or the function in which we have defined them.

Ø  We can declare the very same static variable multiple times, but we can only assign it a single time.

Ø  The initial value of a static integral variable, by default, is 0. Else, it is null.

Ø  We use the static keyword in the case of a static variable.

Ø  The visibility of any static global variable stays limited to that file in which we have declared it.

Static Storage Class (Example)

            #include<stdio.h>

            static float f;

            static int i;

            static char c;

            static char s[100];

            void main () {

                  printf(“%d %d %f %s”,c,i,f); // the initial default value of c, i, and f will be printed.

            }

            #include<stdio.h>

            void sum() {

                 static int x = 20;

                 static int y = 34;

                 printf(“%d %d \n”,x,y);

                 x++;

                 y++;

            }

            void main() {

                  int a;

                  for(a = 0; a< 3; a++)  {

                        sum(); // Given static variables will hold their values between the various function calls.

                  }

            }

Register Storage Class

Ø  We use the register storage class for defining the local variables that must be stored in any register, and not in a RAM.

Ø  It means that the maximum size of this variable is equal to that of the register size (it is usually one word).

Ø  Also, we cannot apply the ‘&’ unary operator to it because it has no memory location.

Ø  For example: register int miles;

Ø  We must only use the register in the case of those variables which require quick access, such as the counters.

Ø  We must also note that defining a register doesn’t mean that this variable would be stored in any register.

Ø  It rather means that this variable MIGHT or might not be stored in a register. It totally depends on the hardware and also the restrictions of implementation.

Features of Register Storage Class

Ø  Those variables that we define as the register have their memory allocation into the CPU registers. It depends totally upon the size of the memory that remains in the CPU.

Ø  Its access time is comparatively much faster than that of the automatic variables.

Ø  One cannot dereference a register variable. In other words, one cannot make use of the ‘&’ operator in the case of a register variable.

Ø  The default initial value of any given register local value will always be 0.

Ø  We use the register keyword for the variable that must be stored in a CPU register. However, whether a variable must be stored in a register or not is always going to be the choice of the compiler.

Ø  One can easily store the pointers in a register. It means that any register is capable of storing the given variable’s address.

Ø  We cannot store a variable into a register since we can’t really utilize more than one storage specifier for the very same variable.

Register Storage Class (Example)

            #include <stdio.h>

            int main()

            {

            register int x; // A variable x has memory allocation in the CPU register. Here, the initial value of x, by default, is 0.

            printf(“%d”,x);

            }

 

 

 


             

             

 

             

             

             

             

 


No comments:

Post a Comment

Research in Social Science

   C  Concept of Research in Social Science -         Understanding the concept of Research Methods, Techniques and Tools: Interview, Fo...