Article

EDP

C & DS

Engg.Chemistry

Engg.Physics

FUNCTIONS

  • D. Vijay Kumar

    Asst. Prof., Dept IT

    MGIT, Hyd

    Definition: Modules in C are called functions. A function in C is defined to be the program segment that carries out some specific, well defined task. A function is a block of code that has a name and it has a property that it is reusable i.e. it can be executed from as many different points in a C Program as required.
    There are two types of functions:

    Library functions: C standard library provides a rich collection of functions for performing I/O operations, mathematical calculations, string manipulation operations etc.For example, sqrt(x) is a function to calculate the square root of a number provided by the C standard library and included in the <math.h>header file.Note that each program in C has a function called main which is used as the root function of calling other library functions.
    Programmer Defined functions: In C, the programmers can write their own functions and use them in their programs.
    The user defined function can be explained with three elements.
    1. Function definition
    2. Function call
    3. Function declaration
    The function definition is an independent program module that is specially written to implement the requirements of the function. In order to use this function we need to invoke it at a required place in the program. This is known as function call. The program that calls the function is known as calling program or calling function. The calling program should declare any function that is to be used later in the program. This is known as the function declaration or the function prototype.
    Structure of a function:
    There are two main parts of the function. The function header and the function body.
    Consider the following example:
    int sum(int x, int y)
         {
         int ans = 0;
         ans = x + y;
         return ans
         }
    Function Header
    In the first line of the above code int sum(int x, int y)
    It has three main parts
    1. The name of the function i.e. sum
    2. The parameters of the function enclosed in paranthesis
    3. Return value type i.e. int
    Function Body
    Whatever is written with i n { } in the above example is the body of the function.
    Function prototype: Function prototypes are always declared at the beginning of the program indicating the name of the function, the data type of its arguments which is passed to the function and the data type of the returned value from the function.
    Ex: int square( int);
    The prototype of a function provides the basic information about a function which tells the compiler that the function is used correctly or not. It contains the same information as the function header contains. The prototype of the function in the above example would be like int sum (int x, int y);
    The only difference between the header and the prototype is the semicolon ; there must the a semicolon at the end of the prototype.
    Categories of functions:
    A function depending on whether arguments are present or not and whether value is returned or not, may belong to one of the following categories:
    1. Functions with no arguments and no return values
    2. Functions with arguments and no return values
    3. Fucntions with arguments and a return value
    4. Functions with no arguments but a return value
    Example programs:
    /* The program illustrates the functions with no arguments and no return value*/
    #include<stdio.h>
    void add(void);
    void main()
       {
         add();
         }
         void add(void)
         {
         int x,y,sum;
         printf(“Enter any two integers:”);
         scanf(“%d%d”,&x,&y);
         sum=x+y;
         printf(“The sum id %d”,sum);
       }
    Output:
    Enter any two integers: 2 4 The sum is 6
    /* The program illustrates the functions with arguments and no return value*/
    #include<stdio.h>
    void add(int a,int b);
    void main()
      {
         int x,y,;
         printf(“Enter any two integers:”);
         scanf(“%d%d”,&x,&y);
         add(x,y);
         }
         void add(int a,int b)
         {
         int sum;
         sum=a+b;
         printf(“The sum id %d”,sum);
      }
    Output:
    Enter any two integers: 2 4 The sum is 6
    /* The program illustrates the functions with arguments and a return value*/
    #include<stdio.h>
    int add(int a,int b);
    void main()
      {
         int x,y,sum;
         printf(“Enter any two integers:”);
         scanf(“%d%d”,&x,&y);
         sum=add(x,y);
         printf(“The sum id %d”,sum);
         }
         int add(int a,int b)
         {
         int c;
         c=a+b;
         return c;
      }
    Output:
    Enter any two integers: 2 4 The sum is 6
    /* The program illustrates the functions with no arguments and but a return value*/
    #include<stdio.h>
    int add(void);
    void main()
      {
         int sum;
         sum=add();
         printf(“The sum id %d”,sum);
         }
         void add(void)
         {
         int x,y,c;
         printf(“Enter any two integers:”);
         scanf(“%d%d”,&x,&y);
         c=x+y;
         return c;
      }
    Output:
    Enter any two integers: 2 4 The sum is 6
    Inter function Communication:
    Although the calling and called functions are two separate entities, they need to communicate to exchange data. The data flow between the calling and called functions can be divided into
    three strategies:
    1. A downward flow from the calling to the called function,
    2. An upward flow from the called to the calling function
    3. A bidirectional flow from both the directions.
    Downward flow:
    Here the calling function sends data to the called function. No data flows in the opposite direction.
    Example program:
    void downfun(int x,int y);
    int main()
      {
         int a=5;
         downfun(a,15);
         printf(“%d”,a);
         return 0;
         }
         void downflun(int x, int y)
         {
         x=x+y;
         return;
      }
    Upward flow:
    This occurs when the called function sends data back to the called function with out receiving any data from it.
    Example program:
    void upfun(int *ax,int *ay);
    int main(void)
      {
         int a; int b;
         upfun(&a,&b); printf(“%d %d\n”,a,b); return 0;
         }
         void upfun(int *ax,int *ay)
         {
         *ax=23;
         *ay=8;
         return;
      }
    Bidirecitonal flow:
    This occurs when the calling function sends data down to the called function. During or at the end of its processing, the called function then sends data up to the calling function.
    Types of function calls
    Call by Value: When a function is called by an argument/parameter the copy of the argument is passed to the function. If the argument is a normal (non-pointer) value a possible change on the copy of the argument in the function does not change the original value of the argument. However, given a pointer/address value any change to the value pointed by the pointer/address changes the original argument.
    Ex: The following program is to calculate and print the area and the perimeter of a circle. by using Call by value approach
    #include<stdio.h>
    #define pi 3.14 float area(float);
    float perimeter(float);
    int main( )
      {
         float r, a, p;
         printf(“Enter the radius\n”);
         scanf(“%f”,&r);
         a = area(r);
         p = perimeter(r);
         printf(“The area = %.2f, \n The Perimeter = %.2f”, a, p);
         return 0;
         }
         float area(float x)
         {
         return pi*r*r;
         }
         float perimeter(float y)
         {
         return 2.0*pi*r;
      }
    Call by Reference: When a function is called by an argument/parameter which is a pointer(address of the argument) the copy of the address of the argument is passed to the function. Therefore a possible change on the data at the referenced address change the original value of the argument.
    Ex: The following program is to calculate and print the area and the perimeter of a circle. by using Call by reference approach
    #include<stdio.h>
    #define pi 3.14
    void area_perimeter(float, float *, float *);
    int main( )
      {
         float r, a, p;
         printf(“Enter the readius\n”);
         scanf(“%f”,&r);
         area_perimeter(r,&a,&p);
         printf(“The area = %.2f, \n The Perimeter = %.2f”, a, p);
         return 0;
         }
         void area_perimeter(float x, float *aptr, float *pptr);
         {
         *aptr = pi*x*x;
         *pptr = 2.0*pi*x;
      }
    Recursion:
    Recursion is a process in which a function calls itself.
    Example:
    Recursion()
         {
         printf("Recursion !");
         Recursion();
         }
    Program :
    /* Program to demonstrate recursion */
    #include<stdio.h>
    int fact(int x);
    void main()
      {
         int a,f;
         clrscr();
         printf(“Enter any integer:”);
         scanf(“%d”,&a);
         f=fact(a);
         printf(“The factorial of %d is %d”,a,f);
         }
         int fact(int x)
         {
         if(x==0) return 1;
         else
         return(x*fact(x-1));
      }
    Output:
    Enter any integer:5
    The factorial of 5 is 120
    Features :
    * There should be at least one if statement used to terminate recursion. 
    * It does not contain any looping statements. 
    Advantages :
    * It is easy to use. 
    * It represents compact programming structures. 
    Disadvantages :
    * It is slower than that of looping statements because each time function is called.
    Standard Functions:
    C provides a rich collection of standard functions whose definitions have been written and are ready to be used in our programs.
    * Absolute value function: 
    * An absolute value is the positive rendering of the value regardless of its sign. 
    * abs(3) returns 3
    Ceiling function:
    * A ceiling is the smallest integral value greater than or equal to a number. 
    * ceil(3.001)=4 
    * Floor function: 
    * floor(1.2) returns 1.0 
    * Truncate function: 
    * The truncate functions return the integral in the direction of 0. They are the same as the floor function for positive numbers and the same as ceiling function for negative  numbers. 
    * trunc(-1.1) returns -1.0 
    * trunc(1.9) returns 1.0 
    * Round function: 
    * The round functions return the nearest integral value. 
    * round(1.9)=2.0 
    * Power function: 
    * The power (pow) function returns the value of the raised to the power y. 
    * pow(3.0,4.0) return 81.0 
    * Square root function: 
    * The square root functions return the non negative square root of a number. An error occurs if  the number is negative. 
    * sqrt(25) returns 5.0 
    The Preprocessor Directives
    The C preprocessor provides several tools that are not available in other high–level languages. The programmer can use these tools to make his program more efficient in all aspects.
    Working of preprocessor
    When a command is given to compile a C program, the programs run automatically through the preprocessor. The preprocessor is a program that modifies the C source program according to directives supplied in the program. An original source program usually is stored in a file. The preprocessor does not modify this program file, but creates a new file that contains the processed version of the program. This new file is then submitted to the compiler. Some compilers enable the programmer to run only the preprocessor on the source program and to view the results of the preprocessor stage.
    All preprocessor directives begin with the number or sharp sign (#).They must start in the first column, and no space is required between the number sign and the directive. The directive is terminated not by a semicolon, but by the end of the line on which it appears.
    The C preprocessor is a collection of special statements called directives that are executed at the beginning of the compilation process. The #include and # define statements are preprocessor directives.
    # define DIRECTIVE
    The #define directive is used to define a symbol to the preprocessor and assign it a value. The symbol is meaningful to the preprocessor only in the lines of code following the definition. For example, if the directive #define NULL 0 is included in the program, then in all lines following the definition, the symbol NULL is replaced by the symbol. If the symbol NULL is written in the program before the definition is encountered, however, it is not replaced. The # define directive is followed by one or more spaces or tabs and the symbol to be defined. The syntax of a preprocessor symbol is the same as that for a C variable or function name. It cannot be a keyword or a variable name used in the program; if it is so a syntax error is detected by the compiler.
    Constants:
    A common use for defined symbols is the implementation of namedconstants. The following are examples of constants in C:
    23, „a‟, “hello”
    Any of these can be assigned to a defined preprocessor
    symbol:
    #define INTEGER 23
    #define CHARACTER „a‟
    A defined symbol can specify only a complete constant.
    MACROS
    When a constant is associated with a defined symbol, the characters making up the constants are assigned , not the numeric value of the constant. The definition #define EOF -1 really assigns the string “-1” to EOF. The preprocessor replaces the symbol EOF by the characters “-1” without any consideration of the meaning of the two characters. When a preprocessor symbol is defined as a segment of text, it is more generally called a macro. Macros are very useful in making C code more readable and compact. For example, some programmers include the following definitions in all their programs:
    The # undef Directive:-
    If a preprocessor symbol has already been defined, it must be undefined before being redefined. This is accomplished by the #undef directive, which specifies the name of the symbol to be undefined. It is not necessary to perform the redefinition at the beginning of a program. A symbol can be redefined in the middle of a program so that it has one value in the first part and another value at the end. A symbol need not be redefined after it is undefined.
    The #include Directive:-
    Often a programmer accumulates a collection of useful constants and macro definitions that are used in almost every program. It is desirable to be able to store these definitions in a file that can be inserted automatically into every program. This task is performed by the #include directive.
    Storage Classes
    A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program.
    Scope: The scope of variable determines over what region of the program a variable is actually available for use.
    Visibility: The program‟s ability to access a variable from the memory.
    Lifetime: Life time refers to the period during which a variable retains a given value during the execution of a program.
    Scope rules:
    1. The scope of a global variable is the entire program file.
    2. The scope of a local variable begins at point of declaration and ends at the end of the block or function in which it is declared.\
    3. The scope of a formal function argument is its own function.
    4. The life time of an auto variable declared in main is the entire program execution time, although its scope is only the main function.
    5. The life of an auto variable declared in a function ends when the function is exited.
    6. All variables have visibility in their scope , provided they are not declared again.
    7. A variable is redeclared within its scope again, it loses its visibility in the scope of the redeclared variable.
    These are following storage classes which can be used in a C Program:
    * auto 
    * register 
    * static 
    * extern 
    auto - Storage Class
    auto is the default storage class for all local variables and the local variable is known only to the function in which it is declared. If the value is not assigned to the variable of type auto.
    the default value is garbage value.
    Syntax :
    auto [data_type] [variable_name];
    Example :
    auto int a;
    Program :
    /* Program to demonstrate automatic storage class.*/
    #include <stdio.h>
    #include <conio.h>
    void main()
      {
         auto int i=10;
         clrscr();
         {
         auto int i=20;
         printf("\n\t %d",i);
         }
         printf("\n\n\t %d",i);
         getch();
      }
    Output :
    20
    10
    register - Storage Class
    Register is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and cant have the unary '&' operator applied to it (as it does not have a memory location). If the value is not assigned to the variable of type register the default value is garbage value.
    Syntax :
    register [data_type] [variable_name];
    Example :
    register int a;
    When the calculations are done in CPU, the value of variables are transferred from main memory to CPU. Calculations are done and the final result is sent back to main memory. This leads to slowing down of processes. Register variables occur in CPU and value of that register variable is stored in a register within that CPU. Thus, it increases the resultant speed of operations. There is no waste of time, getting variables from memory and sending it to back again.It is not applicable for arrays, structures or pointers.It cannot be used with static or external storage class.
    Program :
    /* Program to demonstrate register storage class.*/
    #include <stdio.h>
    #include <conio.h>
    void main()
      {
         register int i=10;
         clrscr();
         {
         register int i=20;
         printf("\n\t %d",i);
         }
         printf("\n\n\t %d",i);
         getch();
      }
    Output :
    20
    10
    static - Storage Class
    static is the default storage class for global variables. As the name suggests the value of static variables persists until the end of the program.Static can also be defined within a function. If this is done the variable is initalised at run time but is not reinitalized when the function is called. This inside a function static variable retains its value during vairous calls. If the value is not assigned to t he variable of type static the default value is zero.
    Syntax :
    static [data_type] [variable_name];
    Example :
    static int a;
    There are two types of static variables:
    a) Local Static Variable
    b) Global Static Variable
    Static storage class can be used only if we want the value of a variable to persist between different function calls.
    Program :
    /* Program to demonstrate static storage class. */
    #include <stdio.h>
    #include <conio.h>
    void main()
      {
         int i;
         void incre(void);
         clrscr();
         for (i=0; i<3; i++)
         incre();
         getch();
         }
         void incre(void)
         {
         int avar=1;
         static int svar=1;
         avar++;
         svar++;
         printf("\n\n Automatic variable value : %d",avar);
         printf("\t Static variable value : %d",svar);
      }
    Output :
    Automatic variable value : 2 Static variable value : 2
    Automatic variable value : 2 Static variable value : 3
    Automatic variable value : 2 Static variable value : 4
    extern - Storage Class
    Variables that are both alive and active throughout the entire program are known as external variables. extern is used to give a reference of a global variable that is visible to all the program files. If the value is not assigned to the variable of type static the default value is zero.
    Syntax :
    extern [data_type] [variable_name];
    Example :
    extern int a;
    The variables of this class can be referred to as 'global or external variables.' They are declared outside the functions and can be invoked at anywhere in a program.
    Program :
    /* Program to demonstrate external storage class.*/
    #include <stdio.h>
    #include <conio.h>
    extern int i=10;
    void main()
      {
         int i=20;
         void show(void);
         clrscr();
         printf("\n\t %d",i);
         show();
         getch();
         }
         void show(void)
         {
         printf("\n\n\t %d",i);
      }
    Output :
    20
    10
    Type qualifiers:
    The type qualifier adds three special attributes to types: const, volatile and restrict.
    Constants:
    The keyword for the constant type qualifier is const. A constant object must be initialized when it is declared because it cannot be changed later. A simple constant is shown below:
    const double PI=3.1415926
    Volatile:
    The volatile qualifier tells the computer that an object value may be changed by entities other than this program.
    volatile int x;
    Restricted:
    The restrict qualifier which is used only with pointers, indicates that the pointer is only the initial way to access the dereferenced data.
    restrict int *ptr;
    ARRAYS
    Definition:
    An array is a collective name given to a group of similar elements. These similar elements could be all integers or all floats or all characters etc.
    Usually, the array of characters is called a “string”, where as an array of integers or floats is called simply an array. All elements of any given array must be of the same type i.e we can‟t have an array of 10 numbers, of which 5 are ints and 5 are floats.
    Declaration of an Array
    Arrays must be declared before they can be used in the program. Standard array declaration is as: type variable_name[lengthofarray];
    Here type specifies the variable type of the element which is going to be stored in the array.
    Ex: double height[10];
    float width[20];
    In C Language, array starts at position 0. The elements of the array occupy adjacent locations in memory. C Language treats the name of the array as if it was a pointer to the first element This is important in understanding how to do arithmetic with arrays. Any item in the array can be accessed through its index, and it can be accesed any where from with in the program. So
    m=height[0];
    variable m will have the value of first item of array height.
    Initializing Arrays
    The following is an example which declares and initializes an array of nine elements of type int. Array can also be initialized after declaration.
    int scores[9]={23,45,12,67,95,45,56,34,83};
              
    Copy one array into another:
    There is no such statement in C language which can directly copy an array into another array. So we have to copy each item seperately into another array. The following program illustrates the copying of elements of one array to another array:
    #include <stdio.h>
    int main()
         {
         int iMarks[4];
         short newMarks[4];
         iMarks[0]=78;
         iMarks[1]=64;
         iMarks[2]=66;
         iMarks[3]=74;
         for(i=0; i<4; i++)
         newMarks[i]=iMarks[i];
         for(j=0; j<4; j++)
         printf("%d\n", newMarks[j]);
         return 0;
         }
    To summarize, arrays provide a simple mechanism where more than one elements of same type are to be used. We can maintain, manipulate and store multiple elements of same type in one array variable and access them through index.
    Two dimensional arrays
    C allows us to define the table of items by using two dimensional arrays.
    Declaration:
    Two dimensional arrays are declared as follows:
    type array_name[row_size][column_size];
    Initialization
    Like one dimensional arrays, two dimensional arrays may be initialized by following their declaration with a list of initial values enclosed in braces.
    Ex: int table[2][3]={0,0,0,1,1,1};
    Initializes the elements of first row to zero and second row to one. The initialization is also done row by row. The above statement can be equivalently written as
    Ex: int table[2][3]={0,0,0},{1,1,1}};
    The following is a sample program that stores roll numbers and marks obtained by a student side by side in matrix
    main ( )
       {
         int stud[4] [2];
         int i, j;
         for (i =0; i < =3; i ++)
         {
         printf ("\n Enter roll no. and marks");
         scanf ("%d%d", &stud [i] [0], &stud [i] [1] );
         }
         for (i = 0; i < = 3; i ++)
         printf ("\n %d %d", stud [i] [0], stud [i] [1]):
       }
    Multidimensional Arrays
    C allows arrays of three or more dimensions. The general form of multidimensional array is type array_name[s1][s2]…..[s3]; where si is the size of ith dimension..
    Ex: int survey[3][5][12];
    survey is a 3 dimensional array.
    Inter function communication:
    Passing arrays through functions:
    Like the values of simple variables, it is also possible to pass the values of an array to a function. To pass an array to a called function, it is sufficient to list the name of the array, without any subscripts and the size of the array as arguments.
    Ex: largest(a,n);
    will pass all the elements contained in the array a of size n. The called function expecting this call must be appropriately defined.
    Example program:
    main()
       {
         float largest();
         static float value[4]={10,-4,2,-3};
         printf(“%f”,largest(value,4));
         }
         float largest(a,n) float a[];
         int n;
         {
         int i; float max;
         max=a[0];
         for(i=1;i<n;i++)
         if(max<a[i])
         max=a[i];
         return(max);
       }
    To process arrays in a large program, we have to be able to pass them to functions. We can pass arrays in two ways: pass individual elements or pass the whole array.

     

Industry      Interaction

Higher Education

Job Skills

Soft Skills

Comm. English

Mock Test

E-learning