Published by: Nuru
Published date: 21 Jun 2021
There are three different types of functions:
Let us consider the following program
/* Program to illustrate a function with no argument and no return values*/ #include
main()
{
statement1();
starline();
statement2();
starline();
}
/*function to print a message*/
statement1()
{
printf(“\n Sample subprogram output”);
}
statement2()
{
printf(“\n Sample subprogram output two”);
}
starline()
{
int a;
for (a=1;a<60;a++)
printf(“%c”,‟*‟);
printf(“\n”);
}
In the above example, there is no data transfer between the calling function and the called function. When a function has no arguments it does not receive any data from the calling function. Similarly, when it does not return value the calling function does not receive any data from the called function. A function that does not return any value cannot be used in an expression it can be used only as an independent statement.
The nature of data communication between the calling function and the arguments to the called function and the called function does not return any values to the calling function this shown in the example below:
Consider the following:
Function calls containing appropriate arguments. For example the function call value (500,0.12,5)
Would send the values 500,0.12 and 5 to the function value (p, r, n) and assign values 500 to p, 0.12 to r, and 5 to n. the values 500,0.12 and 5 are the actual arguments that become the values of the formal arguments inside the called function.
Both the arguments actual and formal should match in number type and order. The values of actual arguments are assigned to formal arguments on a one to one basis starting with the first argument as shown below:
main()
{
function1(a1,a2,a3……an)
}
function1(f1,f2,f3….fn);
{
function body;
}
Here a1, a2, a3 are actual arguments and f1, f2, f3 are formal arguments.
The no of formal arguments and actual arguments must be matching to each other suppose if actual arguments are more than the formal arguments, the extra actual arguments are discarded. If the numbers of actual arguments are less than the formal arguments then the unmatched formal arguments are initialized to some garbage values. In both cases, no error message will be generated.
The formal arguments may be valid variable names; the actual arguments may be variable names expressions or constants. The values used in actual arguments must be assigned values before the function call is made.
When a function call is made only a copy of the values actual arguments are passed to the called function. What occurs inside the functions will have no effect on the variables used in the actual argument list.
Let us consider the following program
/*Program to find the largest of two numbers using function*/ #include
main()
{
int a,b;
printf(“Enter the two numbers”);
scanf(“%d%d”,&a,&b);
largest(a,b);
}
/*Function to find the largest of two numbers*/
largest(int a, int b)
{
if(a>b)
printf(“Largest element=%d”,a);
else
printf(“Largest element=%d”,b);
}
in the above program, we could make the calling function to read the data from the terminal and pass it on to the called function. But function does not return any value.
The function of the type Arguments with return values will send arguments from the calling function to the called function and expects the result to be returned back from the called function back to the calling function. To assure a high degree of portability between programs a function should generally be coded without involving any input-output operations. For example, different programs may require different output formats for displaying the results. These shortcomings can be overcome by handing over the result of a function to its calling function where the returned value can be used as required by the program.
The arguments passed to function can be of two types namely
The first type refers to call by value and the second type refers to call by reference.
For instance, consider program 1:
main()
{
int x=50, y=70;
interchange(x,y);
printf(“x=%d y=%d”,x,y);
}
interchange(x1,y1);
int x1,y1;
{
int z1;
z1=x1;
x1=y1;
y1=z1;
printf(“x1=%d y1=%d”,x1,y1);
}
Here the value to function interchange is passed by value.
Consider program2
main()
{
int x=50, y=70;
interchange(&x,&y);
printf(“x=%d y=%d”,x,y);
}
interchange(x1,y1);
int *x1,*y1;
{
int z1;
z1=*x1;
*x1=*y1;
*y1=z1;
printf(“*x=%d *y=%d”,x1,y1);
}
Here the function is called by reference. In other words, the address is passed by using symbol & and the value is accessed by using symbol *.
The main difference between them can be seen by analyzing the output of program1 and program2.
The output of program1 that is called by value is
x1=70 y1=50
x=50 y=70
But the output of program2 that is called by reference is
*x=70 *y=50
x=70 y=50
This is because in case of call by value the value is passed to function named as an interchange and there the value got interchanged and got printed as
x1=70 y1=50
and again since no values are returned back and therefore original values of x and y as in the main function namely
x=50 y=70 got printed.
A recursive function is a function that calls itself. When a function calls another function and that second function calls the third function then this kind of function is called nesting of functions. But a recursive function is the function that calls itself repeatedly.
An example program to find out factorial of a given number using Recursion:
int fact(int);
void main()
{
int n, fac;
clrscr();
printf("Enter the value of n");
scanf("%d",&n);
fac=fact(n);
printf("The factorial of %d is %d",n,fac);
getch();
}
int fact(int n)
{
if(n= =1)
return(1);
else
return fact(n-1)*n;
}
⚫ Variables in C are categorized into four different storage classes according to the scope and lifetime of variables:
1. Automatic variables
2. External variables
3. Static variables
4. Register variables
Note:
⚫ The scope of a variable determines over what part(s) of the program a variable is actually available for use (active).
⚫ Lifetime refers to the period of time during which a variable retains a given value during the execution of a program (alive).
A local variable is one that is declared inside a function and can only be used by that function. If you declare a variable outside all functions then it is a global variable and can be used by all functions in a program.
#include
// Global variables
int a;
int b;
int Add()
{
return a + b;
}
int main()
{
answer;
// Local variable
a = 5;
b = 7;
answer = Add();
printf("%d\n",answer);
return 0;
}
We can pass an entire array of values into a function just as we pass individual variables. In this task, it is essential to list the name of the array along with functions arguments without any subscripts and the size of the array as arguments
For example:
Largest(a,n);
will pass all the elements contained in the array an of size n. the called function expecting this call must be appropriately defined. The largest function header might look like:
float smallest(array,size);
float array[];
int size;
The function smallest is defined to take two arguments, the name of the array and the size of the array to specify the number of elements in the array. The declaration of the formal argument array is made as follows:
float array[ ];
The above declaration indicates to the compiler that the argument array is an array of numbers. It is not necessary to declare the size of the array here. While dealing with array arguments we should remember one major distinction. If a function changes the value of array elements then these changes will be made to the original array that passed to the function. When the entire array is passed as an argument, the contents of the array are not copied into the formal parameter array instead information about the address of the array elements is passed on to the function. Therefore any changes introduced to array elements are truly reflected in the original array in the calling function.
Rules
1. The function must be called by passing only the array name.
2. In the function definition, we must indicate that the array has two dimensions by including two sets of brackets.
3. The size of the second dimension must be specified.
4. The prototype declaration should be similar to the function header.
//Program to display a matrix
#include
#include
void display(int rix[][2]);
void main()
{
int matrix[2][2], i, j;
clrscr();
printf("Input matrix elements:\t");
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
scanf("%d", &matrix[i][j]);
}
display(matrix);
getch();
}
void display(int mat[][2])
{
int i, j;
printf("\nThe matrix is:\n");
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
printf(" %d\t", mat[i][j]);
printf("\n");
}
}
⚫ When an entire array is passed to a function and if that function changes the values of array elements, then these changes are actually made to the original array that is passed to the function.
⚫ This means that when an entire array is passed as an argument, the contents of the array are not copied into the formal parameter; instead, information about the addresses of array elements is passed on to the function.
⚫ Thus, any changes made to the array elements by the function truly reflected in the original array in the calling function.
⚫ However, this does not apply when an individual element is passed as an argument.
⚫ Since strings are character arrays, the rules for passing strings to functions are similar to those for passing arrays to functions.
⚫ Rules
1. The string to be passed must be declared as a formal argument of the function definition in the function header.
void display(char item_name[])
{
… … … … …
}
2. The function prototype must show that the argument is a string.
void display(char str[]);
3. A call to the function must have a string name without subscripts as its actual argument.
display(name);
where the name is a properly declared string in the calling function.
Note: Like arrays, strings are passed by address.
⚫ A pointer is a variable that stores the memory address of a variable
⚫ Pointer naming is the same as variable naming and it is declared in the same way as other variables but is always preceded by * (asterisk) operator.
⚫ E.g. int b, *a; //pointer declarationa=&b; /* address of b is assigned to pointer variable a */
#include
#include
void swap(int *, int *);
void main()
{
int a=50, b=100;
clrscr();
printf("\n Before swap function call: a=%d and b=%d", a, b);
swap(&a, &b);
printf("\n After swap function call: a=%d and b=%d", a, b);
getch();
}
void swap(int *x, int *y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
printf("\n Values within swap: x=%d and y=%d", *x, *y);
}
⚫ A return statement can return only one value.
⚫ When we need to return more than one value from a function
⚫ We can achieve this by using the arguments not only to receive information but also to send back information to the calling function.
⚫ The arguments that are used to send out information are called output parameters.
⚫ The mechanism of sending back information through arguments are achieved using what is known as the address operator (&) and the indirection operator (*).
void fun(int, int, int *,int *);
void main()
{
int x=100,y=50,s,d;
clrscr();
fun(x, y, &s, &d);
printf("s=%d \td=%d", s, d);
getch();
}
void fun(int a, int b, int *sum, int *diff)
{
*sum=a + b;
*diff=a-b;
}