Unit IV (1)
Unit IV (1)
Unit IV (1)
A function is a group of statements that together perform a task. Every C program has at least one function,
which is main(), and all the most trivial programs can define additional functions.
You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division is such that each function performs a specific task.
A function declaration tells the compiler about a function's name, return type, and parameters. A function
definition provides the actual body of the function.
The C standard library provides numerous built-in functions that your program can call. For example,
strcat() to concatenate two strings, memcpy() to copy one memory location to another location, and many
more functions.
A function can also be referred as a method or a sub-routine or a procedure, etc.
The principles of top-down design and structured programming dictate that a program should be divided into
a main module and its related modules. Each module is in turn divided into sub-modules until the resulting
modules are intrinsic; that is, until they are implicitly understood without further division.
Top-down design is usually done using a visual representation of the modules known as a structure
chart. The structure chart shows the relation between each module and its submodules. The structure chart is
read top-down, left-right. First we read Main Module. Main Module represents our entire set of code to solve
the problem.
Moving down and left, we then read Module 1. On the same level with Module 1 are Module 2 and Module
3. The Main Module consists of three sub-modules. At this level, however we are dealing only with Module
1. Module 1 is further subdivided into three modules, Module 1a, Module 1b, and Module 1c. To write the
code for Module 1, we need to write code for its three sub-modules.
The Main Module is known as a calling module because it has sub-modules. Each of the sub-modules is
known as a called module. But because Modules 1, 2, and 3 also have submodules, they are also calling
modules; they are both called and calling modules.
Communication between modules in a structure chart is allowed only through a calling module. If Module 1
needs to send data to Module 2, the data must be passed through the calling module, Main Module. No
communication can take place directly between modules that do not have a calling-called relationship.
Declaring a Function
A function declaration tells the compiler about a function name and how to call the function. The actual body
of the function can be defined separately.
A function declaration has the following parts −
return_type function_name( parameter list );
For the above defined function max(), the function declaration is as follows −
int max(int num1, int num2);
Parameter names are not important in function declaration only their type is required, so the following is also
a valid declaration −
int max(int, int);
Function declaration is required when you define a function in one source file and you call that function in
another file. In such case, you should declare the function at the top of the file calling the function.
Calling a Function
While creating a C function, you give a definition of what the function has to do. To use a function, you will
have to call that function to perform the defined task.
When a program calls a function, the program control is transferred to the called function. A called function
performs a defined task and when its return statement is executed or when its function-ending closing brace
is reached, it returns the program control back to the main program.
To call a function, you simply need to pass the required parameters along with the function name, and if the
function returns a value, then you can store the returned value. For example −
#include <stdio.h>
/* function declaration */
int max(int num1, int num2);
int main () {
return result;
}
We have kept max() along with main() and compiled the source code. While running the final executable, it
would produce the following result −
Max value is : 200
Signature of a Function:
Function signatures are the "declaration" of the functions in a program. Declaration of a function instructs a
compiler on how to call a function. Function declarations comprise of the following:
1. Name of the function
2. Return type : type of the value that will be returned to the program when function is
executed
3. Parameter(s) : the type of values that you pass to the function while calling it
example :
#include<stdio.h>
int testfun( int , int ); //Function declaration or signature
int main()
{
int a = 2;
int b = 3;
int sum;
sum = testfun(a,b);
printf( "Sum is : \n" , sum);
return 0;
}
Here "testfun" is the name of the function, "int" is the return type, "int" is the type of both the parameters
as declared in the function signature.
Function Name − This is the actual name of the function. The function name and the parameter list
together constitute the function signature.
Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to the
parameter. This value is referred to as actual parameter or argument. The parameter list refers to the
type, order, and number of the parameters of a function. Parameters are optional; that is, a function
may contain no parameters.
Return Type − A function may return a value. The return_type is the data type of the value the
function returns. Some functions perform the desired operations without returning a value. In this
case, the return_type is the keyword void.
Function Body − The function body contains a collection of statements that define what the function
does.
Example
Given below is the source code for a function called max(). This function takes two parameters num1 and
num2 and returns the maximum value between the two −
/* function returning the max between two numbers */
int max(int num1, int num2) {
return result;
}
There are different ways in which parameter data can be passed into and out of methods and functions. Let
us assume that a function B() is called from another function A(). In this case, A is called the “caller
function” and B is called the “called function or callee function”. Also, the arguments which A sends to B
are called actual arguments and the parameters of B are called formal arguments.
Terminology
Formal Parameter: A variable and its type as they appear in the prototype of the func on or method.
Actual Parameter: The variable or expression corresponding to a formal parameter that appears in the
func on or method call in the calling environment.
Modes:
o IN: Passes info from caller to the callee.
o OUT: Callee writes values in the caller.
o IN/OUT: The caller tells the callee the value of the variable, which may be updated by the callee.
Important Methods of Parameter Passing are as follows:
1. Pass By Value
This method uses in-mode semantics. Changes made to formal parameters do not get transmitted back to the
caller. Any modifications to the formal parameter variable inside the called function or method affect only
the separate storage location and will not be reflected in the actual parameter in the calling environment.
This method is also called call by value.
// Passing parameters
func(x, y);
printf("In main, x = %d y = %d\n", x, y);
return 0;
}
Output
In func, a = 12 b = 7
In main, x = 5 y = 7
Note: Languages like C, C++, and Java support this type of parameter passing. Java in fact is strictly call by
value.
Shortcomings of Pass By Value:
Inefficiency in storage alloca on
For objects and arrays, the copy seman cs are costly
2. Pass by reference(aliasing)
This technique uses in/out-mode semantics. Changes made to formal parameter do get transmitted back to
the caller through parameter passing. Any changes to the formal parameter are reflected in the actual
parameter in the calling environment as formal parameter receives a reference (or pointer) to the actual data.
This method is also called as call by reference. This method is efficient in both time and space.
Example
// C program to illustrate
// call by reference
#include <stdio.h>
void swapnum(int* i, int* j)
{
int temp = *i;
*i = *j;
*j = temp;
}
int main(void)
{
int a = 10, b = 20;
// passing parameters
swapnum(&a, &b);
printf("a is %d and b is %d\n", a, b);
return 0;
}
Output
a is 20 and b is 10
Note: C and C++ both support call by value as well as call by reference whereas Java doesn’t support call
by reference.
Shortcomings of Pass by Reference
Many poten al scenarios can occur
Programs are difficult to understand some mes
3. Pass by Name
This technique is used in programming languages such as Algol. In this technique, the symbolic “name” of a
variable is passed, which allows it both to be accessed and updated.
Example
To double the value of C[j], you can pass its name (not its value) into the following procedure.
procedure double(x);
real x;
begin
x:=x*2
end;
In general, the effect of pass-by-name is to textually substitute the argument in a procedure call for the
corresponding parameter in the body of the procedure. Implications of Pass-by-Name mechanism:
The argument expression is re-evaluated each time the formal parameter is passed.
The procedure can change the values of variables used in the argument expression and hence change
the expression’s value.
int main() {
int ageArray[] = {2, 8, 4, 12};
#include <stdio.h>
float calculateSum(float num[]);
int main() {
float result, num[] = {23.4, 55, 22.6, 3, 40.5, 18};
// num array is passed to calculateSum()
result = calculateSum(num);
printf("Result = %.2f", result);
return 0;
}
return sum;
}
Output
Result = 162.50
To pass an entire array to a function, only the name of the array is passed as an argument.
result = calculateSum(num);
However, notice the use of [] in the function definition.
float calculateSum(float num[]) {
... ..
}
This informs the compiler that you are passing a one-dimensional array to the function.
int main() {
int num[2][2];
printf("Enter 4 numbers:\n");
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
scanf("%d", &num[i][j]);
}
}
return 0;
}
// Driver code
int main()
{
int a = 10, b = 20;
swap(a, b);
printf("Values after swap function are: %d, %d",
a, b);
return 0;
}
Output
Values after swap function are: 10, 20
Arguments Passing with pointers
A pointer to a function is passed in this example. As an argument, a pointer is passed instead of a variable
and its address is passed instead of its value. As a result, any change made by the function using the pointer
is permanently stored at the address of the passed variable. In C, this is referred to as call by reference.
Below is the C program to pass arguments to function with pointers:
// C program to swap two values
// without passing pointer to
// swap function.
#include <stdio.h>
// Driver code
int main()
{
int a = 10, b = 20;
printf("Values before swap function are: %d, %d\n",
a, b);
swap(&a, &b);
printf("Values after swap function are: %d, %d",
a, b);
return 0;
}
Output
Values before swap function are: 10, 20
Values after swap function are: 20, 10
Types of Functions
There are two types of functions in C:
1. Library Functions
2. User Defined Functions
1. Library Function
A library function is also referred to as a “built-in function”. A compiler package already exists that contains
these functions, each of which has a specific meaning and is included in the package. Built-in functions have
the advantage of being directly usable without being defined, whereas user-defined functions must be declared
and defined before being used.
For Example:
pow(), sqrt(), strcmp(), strcpy() etc.
#include<stdio.h>
int main()
{
int n1=0,n2=1,n3,i,number;
printf("Enter the number of elements:");
scanf("%d",&number);
printf("\n%d %d",n1,n2);//printing 0 and 1
for(i=2;i<number;++i)//loop starts from 2 because 0 and 1 are already printed
{
n3=n1+n2;
printf(" %d",n3);
n1=n2;
n2=n3;
}
return 0;
}
Output:
Enter the number of elements:15
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Fibonacci Series using recursion in C
Let's see the fibonacci series program in c using recursion.
#include<stdio.h>
void printFibonacci(int n){
static int n1=0,n2=1,n3;
if(n>0){
n3 = n1 + n2;
n1 = n2;
n2 = n3;
prin ("%d ",n3);
printFibonacci(n-1);
}
}
int main(){
int n;
prin ("Enter the number of elements: ");
scanf("%d",&n);
prin ("Fibonacci Series: ");
printf("%d %d ",0,1);
printFibonacci(n-2);//n-2 because 2 numbers are already printed
return 0;
}
Output:
Enter the number of elements:15
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
malloc() function in C
The malloc() function allocates single block of requested memory.
It doesn't initialize memory at execution time, so it has garbage value initially.
It returns NULL if memory is not sufficient.
The syntax of malloc() function is given below:
ptr=(cast-type*)malloc(byte-size);
Example:
ptr = (int*) malloc(100 * sizeof(int));
Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And, the pointer ptr holds
the address of the first byte in the allocated memory.
calloc() function in C
The calloc() function allocates multiple block of requested memory.
It initially initialize all bytes to zero.
It returns NULL if memory is not sufficient.
The syntax of calloc() function is given below:
ptr=(cast-type*)calloc(number, byte-size);
Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the size of the float.
free() function in C
The memory occupied by malloc() or calloc() functions must be released by calling free() function.
Otherwise, it will consume memory until program exit.
Let's see the syntax of free() function.
free(ptr) ;
Example of malloc() and free()
// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
return 0;
}
Output
Enter number of elements: 3
Enter elements: 100
20
36
Sum = 156
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
int main() {
int *ptr, i , n1, n2;
printf("Enter size: ");
scanf("%d", &n1);
free(ptr);
return 0;
}
Output
Enter size: 2
Addresses of previously allocated memory:
26855472
26855476
When allocating memory for arrays of different data types in programming, you need to consider the size of
each data type as it determines the total memory required for the array.
int *intArray = (int *)malloc(sizeof(int) * 10); // Allocating memory for an array of 10
integers
double *doubleArray = new double[20]; // Allocating memory for an array of 20 doubles in C++
char *charArray = (char *)malloc(sizeof(char) * 5); // Allocating memory for an array of 5
characters