ALL SIR NOTES HAVE BEEN UPLOADED HERE.
A function is a self-contained block of statements that performs a specific task. If a program is divided into functional parts, then each part may be independently coded and later combined into a single unit. These independently coded programs are called subprograms that are much easier to understand, debug, and test. In C, such subprograms are referred to as ‘functions’. This ‘division’ approach clearly results in a number of advantages.
It improve the readability of code.
The length of a source program can be reduced by using functions.
It improves the reusability of the code, same function can be used in any program rather than writing the same code from scratch.
Debugging of the code would be easier, as errors are easy to be traced.
A function may be used by many other programs.
It facilitates top-down modular programming.
There are two types of function in C language:
Library Function
User-Defined Function
Library Functions: The standard library functions are built-in functions in C programming. Library functions are the inbuilt function in C that are grouped and placed at a common place called the library. Such functions are used to perform some specific operations. For example, printf() is a library function used to print on the console. The library functions are created by the designers of compilers. All C standard library functions are defined inside the different header files saved with the extension .h. We need to include these header files in our program to make use of the library functions defined in such header files.
User-Defined Functions: A User-defined functions on the other hand, are those functions which are defined by the user at the time of writing program. These functions are made for code reusability and for saving time and space.
Modular programming is a strategy applied to the design and development of software systems. It is defined as organizing a large program into small, independent program segments called modules (functions) that are separately named and individually callable program units. These modules are carefully integrated to become a software system that satisfies the system requirements. It is basically a “divide-and-conquer” approach to problem solving. In C, each module refers to a function that is responsible for a single task. Some characteristics of modular programming are as follows:
Each module should do only one thing.
Communication between modules is allowed only by a calling module.
A module can be called by one and only one higher module.
No communication can take place directly between modules that do not have calling-called relationship.
All modules are designed as single-entry, single-exit systems using control structures.
In order to make use of a user-defined function, we need to establish three elements that are related to functions.
Function declaration: A function must be declared in a program to tell the compiler about the function name, function arguments, and return type.
Function definition: It contains the actual statements which are to be executed. It is the most important aspect to which the control comes when the function is called.
Function call: Function can be called from anywhere in the program. The parameter list must not differ in function calling and 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 the function call. The program that calls the function is referred to as the 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 function prototype. Syntax of a function is:
Return_type function_name ( argument list )
{
//block of statements
}
A function definition, also known as function implementation shall include the following elements:
Function name
Return type
List of parameters
Local variable declarations
Function statements
Return statement
List of parameters contains variables name along with their data types. These arguments are kind of inputs for the function.
Return type can be of any data type such as char, int, short, float, double etc. A C function may or may not return a value from the function. If you don’t have to return any value from the function, use void for the return type.
A function, depending on whether arguments are present or not and whether a value is returned or not, may belong to one of the following categories:
Functions with NO arguments and NO return values.
Functions WITH arguments and NO return values.
Functions NO arguments and WITH return values.
Functions WITH arguments and WITH return values.
Functions that return multiple values.
The parameters specified in the function call are known as actual parameters and those specified in the function declaration are known as formal parameters. The scope of formal parameters is limited to its function only.
Parameter passing is a mechanism for communication of data and information between the calling function (caller) and the called function (callee). It can be achieved either by passing the value or address of the variable. C supports the following two types of parameter passing schemes:
Pass By Value or Call by Value
Pass By Address/Pointer/Reference or Call by Reference
The value of the actual parameters is copied into the formal parameters.
We cannot modify the value of the actual parameter by the formal parameter.
In call by value, different memory is allocated for actual and formal parameters since the value of the actual parameter is copied into the formal parameter.
The actual parameter is the argument which is used in the function call whereas formal parameter is the argument which is used in the function definition.
Pass-by-value mechanism does not change the contents of the argument variable in the calling function, even if they are changed in the called function.
void swap (int x, int y)
{
int t;
t = x;
x = y;
y = t;
printf(“After swaping in swap fun”);
printf(“\nx = %d y = %d”, x, y);
}
int main()
{
int a, b;
printf(“Enter two numbers: ”);
scanf((%d%d”,&a, &b);
swap ( a, b );
printf(“\nAfter calling swap function”);
printf(“\n a = %d b = %d”, a, b);
}
In call by reference, the address of the variable is passed into the function call as the actual parameter.
The value of the actual parameters can be modified by changing the formal parameters since the address of the actual parameters is passed.
In call by reference, the memory allocation is similar for both formal parameters and actual parameters. All the operations in the function are performed on the value stored at the address of the actual parameters, and the modified value gets stored at the same address.
In Pass-by-Address mechanism, instead of passing the value, the address of the variable is passed in the function. The de-referencing operator ( * ) is used to access the variable in the called function.
void swap (int * x, int * y)
{
int t;
t = * x;
x = * y;
y = * t;
printf(“After swaping in swap fun”);
printf(“\nx = %d y = %d”, * x, * y);
}
int main()
{
int a, b;
printf(“Enter two numbers: ”);
scanf((%d%d”,&a, &b);
swap ( &a, &b );
printf(“\nAfter calling swap function”);
printf(“\n a = %d b = %d”, a, b);
}
Any function which calls itself is called recursive function, and such function calls are called recursive calls. When a called function in turn calls another function a process of ‘chaining’ occurs. Recursion is a special case of this process, where a function calls itself. For example:
main()
{
printf( “main() is called recursively” )
main();
}
Recursive functions can be effectively used to solve problems where solution is expressed in terms of successively applying the same solution to subsets of the problem. For example, following the C function to generate the nth term of Fibonacci series:
int fibo( int n )
{
if ( n <=0 )
{
printf (“Series cannot be generated”);
return -111; //error state
}
else if ( n == 1 || n == 2)
return 1;
else
return ( fibo(n – 1 ) + fibo( n – 2 ) );
}
#include <stdio.h>
int fact(int);
int main()
{
int num, factorial;
printf(“\nEnter a number: ”);
scanf(“%d”,&num);
factorial = fact(num);
printf(“\nFactorial of %d = %d”, num, factorial);
return 0;
}
int fact(int n)
{
if (n == 0 || n == 1)
return 1;
else
return n * fact(n – 1);
}
(The Scope, Visibility, and Lifetime of Variables)
In C all variables have a data type and also have a storage class. A variable’s storage class tells us the following things about the variable:
Where would the variable be stored?
What would be the default initial value of the variable?
What would be the scope of the variable, i.e., to which statements the value of the variable would be available?
What would be the life of the variable, i.e., how long would the variable exist.
There are four storage classes in C:
Automatic storage class
Register storage class
Static storage class
External storage class
The visibility of the automatic variables is limited to the block in which they are defined.
The scope of the automatic variables is limited to the block in which they are defined.
The automatic variables are initialized to garbage by default.
The memory assigned to automatic variables gets freed upon exiting from the block.
The keyword used for defining automatic variables is auto.
Every local variable is automatic in C by default.
The variables defined as the register is allocated the memory into the CPU registers depending upon the size of the memory remaining in the CPU.
We cannot dereference the register variables, i.e., we cannot use & operator for the register variable.
The access time of the register variables is faster than the automatic variables.
The initial default value of the register local variables is 0.
The register keyword is used for the variable which should be stored in the CPU register. However, it is compiler’s choice whether or not; the variables can be stored in the register.
The variables defined as static specifier can hold their value between the multiple function calls.
Static local variables are visible only to the function or the block in which they are defined.
Default initial value of the static integral variable is 0 otherwise null.
The visibility of the static global variable is limited to the file in which it has declared.
The keyword used to define static variable is static.
Example:
#include <stdio.h>
void print(void);
int main()
{
int i;
for( i = 1; i <= 5; i++)
print();
return 0;
}
void print(void)
{
static int n = 1;
printf(“%4d”,n);
n++;
}
The external storage class is used to tell the compiler that the variable defined as extern is declared with an external linkage elsewhere in the program.
The variables declared as extern are not allocated any memory. It is only declaration and intended to specify that the variable is declared elsewhere in the program.
The default initial value of external integral type is 0 otherwise null.
We can only initialize the extern variable globally, i.e., we cannot initialize the external variable within any block or method.