Module - 4 Functions
A function is a block of code to perform a specific task. Every c program has at least one function
main().
• In modular programming, the program is divided into separate small programs
called modules.
• Each module is designed to perform a specific task. Hence easier to read and write.
● C enables its programmers to break up a program into segments commonly known as
functions, each of which can be written more or less independently of the others.
• Every function in the program is supposed to perform a well defined task. Therefore, the program
code of one function is completely insulated from that of other functions.
The General Form of a Function
The general form of a function is
ret-type function-name(parameter list)
{
body of the function
}
The ret-type specifies the type of data that the function returns. A function may return any type of
data except an array. The parameter list is a comma-separated list of variable names and their
associated types. The parameters receive the values of the arguments when the function is called.
In variable declarations, you can declare several variables to be of the same type by using a comma
separated list of variable names. In contrast, all function parameters must be declared individually,
each including both the type and name. That is, the parameter declaration list for a function takes this
general form:
f(type varname1, type varname2, . . . , type varnameN)
For example, here are a correct and an incorrect function parameter declaration:
f(int i, int k, int j) /* correct */
f(int i, k, float j) /* wrong, k must have its own type specifier */
In the fig, main() calls another function, func1() to perform a well defined task.
• main() is known as the calling function and func1() is known as the called function.
• When the compiler encounters a function call, instead of executing the next statement in the calling
function, the control jumps to the statements that are a part of the called function.
• After the called function is executed, the control is returned back to the calling program.
Geetha N, Dept of CSE BMSCE
It is not necessary that the main() can call only one function, it can call as many functions as it wants
and as many times as it wants. For example, a function call placed within a for loop, while loop or
do-while loop may call the same function multiple times until the condition holds true.
● It is not that only the main() can call other functions. Any function can call any other function. In
the fig. one function calls another, and the other function in turn calls some other function.
Components of a Functions
1. Function Declaration / Function prototype
2. Function Definition
3. Function call
4. Return statement
1. Function Declaration / Function Prototype
● The general format for declaring a function that accepts some arguments and returns some
value as a result can be given as:
return-data-type function-name (data-type variable1,
data-type variable2);
● Naming a function follows the same rules as naming variables.
● A function should have a meaningful name that must be executable code for that function.
● specify the task that the function will perform.
● data-type variable1, … is a list of variables of specified data types. These variables are
passed from the calling function to the called function. They are also known as arguments or
parameters that the called function accepts to perform its task.
Geetha N, Dept of CSE BMSCE
Valid function declarations
1. int find_largest(int a, int b, int c);
↑ return-data-type ↑ function name ↑ variable 3 variable datatype
2. char convert_to_lower(char ch);
3. float avg(int a, int b);
4. double multiply(float a, float b);
5. void swap(int a, int b); → (returns nothing)
6. void print(); → just prints the message, no parameters passed.
● After the declaration of every function, there should be a semicolon. If the semicolon is
missing, the compiler will generate an error message.
● The function declaration is global; therefore, the declared function can be called from any
point in the program.
● Use of argument names in the function declaration statement is optional.
int func(int, char, float); or int func(int num, char ch, float num);
● A function can’t be declared within the body of another function.
● A function having void return-data-type cannot return any value.
● A function having void as its parameter list cannot accept any value.
void print(void); or void print();
● If the function declaration does not specify any return type, then by default, the function
returns an integer value.
sum(int a, int b); accepts 2 integer values from the calling function and in turn returns an integer
value to the caller.
● Some compilers make it compulsory to declare the function before its usage while other
compilers make it optional.
2. Function Definition
● When a function is defined, space is allocated for that function in the memory.
● A function definition has 2 parts: Function header and Function body.
Syntax:
return data-type function-name (datatype var1, datatype var2)
{
statements
return (variable);
}
● The number of arguments and the order of arguments in the function header must be same
as that of the function declaration statement.
Geetha N, Dept of CSE BMSCE
● The function header is same as function declaration. The only difference between the two
is that a function header is not followed by a semicolon.
● The list of variables in the function header is known as the formal parameter list. It may
have zero or more parameters of any data type.
● The function body contains instructions to perform the desired computation in a function.
Function Call
● The function call statement invokes the function.
● When a function is invoked, the compiler jumps to the called function to execute the
statements that are part of that function. Once the called function is executed, the program control
passes back to the calling function.
Syntax:
function-name(variable1, variable2, ...);
● List of variables used in function call is actual parameter list.
● The actual parameters list may contain variable names, expressions or constants.
● If the parameters passed to a function are more than what is specified then the extra
arguments will be discarded.
● If the parameters passed to a function are less than what is specified, then the unmatched
arguments will be initialized to some garbage value.
● If the return type of the function is not void, the value returned by the called function may
be assigned to some variable.
variable-name = func(var1, var2);
Understanding the Scope of a Function
Each function is a discrete block of code. Thus, a function defines a block scope. This means that a
function's code is private to that function and cannot be accessed by any statement in any other
function except through a call to that function. (For instance, you cannot use goto to jump into the
middle of another function.) The code that constitutes the body of a function is hidden from the rest of
the program, and unless it uses global variables, it can neither affect nor be affected by other parts of
the program.
Variables that are defined within a function are local variables. A local variable comes into existence
when the function is entered and is destroyed upon exit. Thus, a local variable cannot hold its value
between function calls.
Example :
#include <stdio.h>
/* Function with parameters */
int add(int a, int b)
{
return a + b;
}
Geetha N, Dept of CSE BMSCE
/* Function without parameters */
int subtract()
{
int x, y;
printf("Enter two numbers for subtraction: ");
scanf("%d %d", &x, &y);
return x - y;
}
int main()
{
int a, b, sum, diff;
printf("Enter two numbers for addition: ");
scanf("%d %d", &a, &b);
sum = add(a, b); /* For addition (with parameters) */
diff = subtract(); /* For subtraction (without parameters) */
printf("\nAddition = %d", sum);
printf("\nSubtraction = %d", diff);
return 0;
}
Output:
Enter two numbers for addition: 10 5
Enter two numbers for subtraction: 20 8
Addition = 15
Subtraction = 12
Function Arguments
When a function is called, the calling function may have to pass some values to the called function.
(i) call by value : in which values of variables are passed by the calling function to the called function.
The programs that we have written.
(ii) call by reference : in which address of variables are passed by the calling function to the called
function.
(iii) Calling Functions with Arrays
1. Call by Value
Geetha N, Dept of CSE BMSCE
● In the call by value method, the called function creates new variables to store the value of
the arguments passed to it. Therefore the called function uses a copy of the actual arguments to
perform its intended task.
● The change made to the parameters passed to the called function will be reflected only in
the called function.
● In the calling function no change will be made to the value of the variables. This is
because all the changes were made to the copy of the variables and not to the actual parameters.
Ex:
#include <stdio.h>
void add(int);
void main()
{
int num = 2;
printf("The num value before calling the function = %d", num);
add(num);
printf("The num value after calling the function = %d", num);
return 0;
}
void add(int n)
{
n = n + 10;
printf("The num value in called function = %d", n);
}
Output
The num value before calling the function = 2
The num value in the called function = 12
The num value after calling the function = 2
In the above program, the called function could not directly modify the value of the argument that
was passed to it. In case the value had to be changed, then the programmer may use the return
statement.
#include <stdio.h>
int add(int);
int main()
{
int num = 2;
printf("The num value before calling the function = %d", num);
num = add(num);
printf("The num value after calling the function = %d", num);
return 0;
}
Geetha N, Dept of CSE BMSCE
int add(int n)
{
n = n + 10;
printf("The num value in the called function = %d", n);
return n;
}
Output
The num value before calling the function = 2
The num value in the called function = 12
The num value after calling the function = 12
Therefore, call by value method is used in 2 cases:
● When the called function does not need to modify the value of the actual parameter. It
simply uses the value of the parameter to perform the task.
● When you want that, the called function should only temporarily modify the value of the
variables and not permanently.
Pros and Cons
● The advantage of using the call by value technique to pass arguments is that arguments
can be variables (e.g., x), literals (e.g., 6) or expressions (e.g., x + 1).
● The disadvantage is that copying data consumes additional storage space. In addition, it
can take a lot of time to copy, thereby resulting in performance penalty especially if the function is
called many times.
2. Call by Reference
● In call by reference, we declare the function parameters as references rather than normal
variables.
● When this is done any changes made by the function to the arguments it receives are
visible in the calling function.
● To indicate that an argument is passed using call by reference, an asterisk (*) is placed
after the type in the parameter list.
● In call-by-reference, a function receives an implicit reference to the argument, rather than
a copy of its value.
Ex:
#include <stdio.h>
void add(int *n);
int main()
{
int num = 2;
printf("The num value before calling the function = %d", num);
add(&num);
Geetha N, Dept of CSE BMSCE
printf("The num value after calling the function = %d", num);
return 0;
}
void add(int *n)
{
*n = *n + 10;
printf("The value of num in called function = %d", *n);
}
Output
The num value before calling the function = 2
The value of num in called function = 12
The num value after calling the function = 12
3. Calling Functions with Arrays
In C, when an array is passed to a function, the base address of the array is passed. Therefore, any
changes made to the array elements inside the function affect the original array. The size of the array is
usually passed separately.
Example: Passing an Array to a Function
#include <stdio.h>
void display(int a[], int n) {
int i;
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
}
int main() {
int arr[5] = {10, 20, 30, 40, 50};
display(arr, 5);
return 0;
}
Output:
10 20 30 40 50
Key Points:
● Array name represents the address of the first element
● No need to use & while passing the array
● Changes inside the function reflect in the original array
● Array size should be passed explicitly
Example: Modifying an Array inside a Function
#include <stdio.h>
Geetha N, Dept of CSE BMSCE
void update(int a[]) {
a[0] = 100;
}
int main() {
int arr[3] = {1, 2, 3};
update(arr);
printf("%d", arr[0]);
return 0;
}
Output:
100
Example: Passing a String to a Function in C
In C, a string is passed to a function as a character array (char[]) or pointer (char *). The function
receives the address of the first character.
Example Program
#include <stdio.h>
void display(char str[]) {
printf("%s", str);
}
int main() {
char name[] = "C Programming";
display(name);
return 0;
}
Output: C Programming
Key Points (for exams):
● String is passed as char[] or char *
● No & is used while passing the string
● Function works on the original string
Example: Passing a String Using char * to a Function
#include <stdio.h>
void display(char *str) {
printf("%s", str);
}
int main() {
char name[] = "System Programming";
Geetha N, Dept of CSE BMSCE
display(name);
return 0;
}
Output: System Programming
The return statement
The return statement is used inside a function to send control back to the calling function. It may also
send a value back to the caller. Once return is executed, the function terminates immediately.
Example:
#include <stdio.h>
int fun() {
return 10;
}
int main() {
printf("%d", fun());
return 0;
}
Output: 10
1. Returning from a Function
When a return statement is executed, the function stops executing further statements and control goes
back to the calling function.
Example:
#include <stdio.h>
int check() {
printf("Before return\n");
return 1;
printf("After return"); // not executed
}
int main() {
check();
return 0;
}
Output:
Before return
2. Returning Values
A function can return a single value of the same type as its return type (int, float, char, etc.). Example:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
Geetha N, Dept of CSE BMSCE
int main() {
printf("%d", add(5, 3));
return 0;
}
Output: 8
3. Returning Pointers
A function can return a pointer (address of a variable). The variable must exist after the function ends
(global or static). Example:
#include <stdio.h>
int* getValue() {
static int x = 50;
return &x;
}
int main() {
int *p = getValue();
printf("%d", *p);
return 0;
}
Output: 50
4. Functions of Type void
A void function does not return any value. It is used when a function performs an action like printing.
Example:
#include <stdio.h>
void display() {
printf("Hello World");
}
int main() {
display();
return 0;
}
Output: Hello World
Multiple return points - A function can have several return statements — they simply end execution
at that point and return the value.
#include <stdio.h>
int sign(int x) {
if (x > 0) return 1;
if (x < 0) return -1;
return 0; // covers x == 0
}
Geetha N, Dept of CSE BMSCE
int main(void) {
printf("%d\n", sign(10)); // 1
printf("%d\n", sign(-3)); // -1
printf("%d\n", sign(0)); // 0
return 0;
}
What Does main( ) Return?
The main( ) function returns an integer to the calling process, which is generally the operating
system. Returning a value from main( ) is the equivalent of calling exit( ) with the same value. If main(
) does not explicitly return a value, the value passed to the calling process is technically undefined.
argc and argv — Arguments to main()
In C, command-line arguments allow values to be passed to a program at the time of execution.
These arguments are received by the main() function using two parameters: argc and argv.
Syntax of main() with arguments
int main(int argc, char *argv[])
OR
int main(int argc, char **argv)
argc (Argument Count)
● argc stores the number of command-line arguments
● It is always at least 1
● The program name itself is counted as the first argument
Example:
./sum 10 20
Here,
argc = 3
argv (Argument Vector)
● argv is an array of character pointers
● Each element points to a string (argument)
● argv[0] → program name
● argv[1] → first argument
● argv[2] → second argument
argv[0] → "./sum"
argv[1] → "10"
Geetha N, Dept of CSE BMSCE
argv[2] → "20"
Example 1: Display command-line arguments
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("Total arguments = %d\n", argc);
for(i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
Execution:
./test C Programming Lab
Output:
Total arguments = 4
argv[0] = ./test
argv[1] = C
argv[2] = Programming
argv[3] = Lab
Example 2: Adding two numbers using argc and argv
Note: Command-line arguments are strings, so we convert them to integers using atoi().
In C, atoi()- Ascii to Integer and atof() Ascii to float are standard library functions used to convert
strings into numeric values. They are commonly used with command-line arguments (argv).
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a, b, sum;
a = atoi(argv[1]);
b = atoi(argv[2]);
sum = a + b;
printf("Sum = %d\n", sum);
return 0;
}
Geetha N, Dept of CSE BMSCE
Execution:
./add 10 20
Output:
Sum = 30
Recursion Function
A recursive function is a function that calls itself to solve a problem. Recursion breaks a
problem into smaller subproblems until a base condition is reached.
Parts of a Recursive Function
1. Base Case – stops the recursion
2. Recursive Call – function calls itself
Without a base case, recursion leads to infinite calls.
General Syntax
return_type function_name(parameters)
{
if (base_condition)
return value;
else
return function_name(smaller_parameters);
}
Example 1: Factorial of a Number
#include <stdio.h>
int fact(int n)
{
if (n == 0)
return 1;
else
return n * fact(n - 1);
}
int main()
{
int n = 5;
printf("Factorial = %d", fact(n));
return 0;
}
Output
Geetha N, Dept of CSE BMSCE
Factorial = 120
How Recursion Works (Factorial of 3)
fact(3)
→ 3 * fact(2)
→ 2 * fact(1)
→ 1 * fact(0)
→1
2. Palindrome Check Using Recursion in C
Example: Palindrome Number Using Recursion
#include <stdio.h>
int reverse(int n, int rev)
{
if (n == 0)
return rev;
return reverse(n / 10, rev * 10 + (n % 10));
}
int main()
{
int num = 121;
int rev = reverse(num, 0);
if (num == rev)
printf("Palindrome");
else
printf("Not Palindrome");
return 0;
}
Output
Palindrome
inline Keyword in C
The inline keyword is used to request the compiler to replace a function call with the actual
function code, instead of performing a normal function call. This helps in reducing function call
overhead.
inline is only a suggestion, not a command. The compiler may ignore it.
Why inline is used
● Avoids overhead of function call (jump, return, stack operations)
Geetha N, Dept of CSE BMSCE
● Improves execution speed for small functions
● Commonly used in header files and macros replacement
Syntax
inline return_type function_name(parameters)
{
statements;
}
Example 1: Inline Function
#include <stdio.h>
inline int square(int x)
{
return x * x;
}
int main()
{
int n = 5;
printf("Square = %d", square(n));
return 0;
}
Output
Square = 25
How it Works (Conceptually)
Without inline:
main() → call square() → execute → return
With inline:
main() → code of square() inserted → execute
When Compiler May Ignore inline
● Function is too large
● Function contains loops or recursion
● Function address is taken using pointer
● Compiler optimization is off
Geetha N, Dept of CSE BMSCE
Dynamic Memory Allocation in C
Dynamic Memory Allocation (DMA) in C is the process of allocating and freeing memory at
runtime using predefined library functions. The memory is allocated from the heap area.
Why Dynamic Memory Allocation?
● Size of data is not known at compile time
● Efficient use of memory
● Required for dynamic arrays, structures, linked lists
● Memory can be increased or decreased during execution
Header File – #include <stdlib.h>
Dynamic Memory Allocation Functions
Function Description
malloc() Allocates memory (uninitialized)
calloc() Allocates memory and initializes to 0
realloc() Changes size of allocated memory
free() Releases allocated memory
malloc() – Memory Allocation
malloc() (memory allocation) allocates a single block of memory of the specified size in bytes.
The allocated memory is not initialized (contains garbage values).
● Allocates memory at runtime
● Returns a void pointer
● Must be type-cast
● Returns NULL if memory allocation fails
● Memory contains garbage values
Syntax
ptr = (data_type *) malloc(size_in_bytes);
Example using malloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
Geetha N, Dept of CSE BMSCE
int *p, n = 5, i;
p = (int *) malloc(n * sizeof(int));
if (p == NULL) {
printf("Memory allocation failed");
return 1;
}
printf("Enter 5 integers:\n");
for (i = 0; i < n; i++) {
scanf("%d", &p[i]);
}
printf("Entered values:\n");
for (i = 0; i < n; i++) {
printf("%d ", p[i]);
}
free(p);
return 0;
}
Sample Input
10 20 30 40 50
Output
Entered values:
10 20 30 40 50
calloc() – Contiguous Allocation
calloc() allocates memory for multiple blocks of the same size and initializes all bytes to zero.
● Allocates contiguous memory
● Initializes memory to 0
● Safer than malloc() when initialization is required
● Returns NULL on failure
Syntax
ptr = (data_type *) calloc(number_of_elements, size_of_each_element);
Example using calloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
Geetha N, Dept of CSE BMSCE
int *p, n = 5, i;
p = (int *) calloc(n, sizeof(int));
if (p == NULL) {
printf("Memory allocation failed");
return 1;
}
printf("Values in array after calloc:\n");
for (i = 0; i < n; i++) {
printf("%d ", p[i]);
}
free(p);
return 0;
}
Output
Values in array after calloc:
00000
realloc() in C (Reallocation of Memory)
Definition
realloc() is used to change the size of previously allocated dynamic memory without losing
the existing data. It can:
● Increase memory size
● Decrease memory size
The memory must be already allocated using malloc() or calloc().
Syntax
ptr = (data_type *) realloc(ptr, new_size_in_bytes);
Key Points (Very Important)
● Existing data is preserved up to the new size
● New memory (if increased) is not initialized
● Returns NULL if reallocation fails
● Old pointer becomes invalid if memory is moved
● Must always assign realloc result to the pointer
How realloc() Works (Concept)
Geetha N, Dept of CSE BMSCE
● If enough space is available → memory size is changed at the same location
● If not → a new memory block is allocated, old data is copied, and old memory is freed
Increasing size
● Old data remains safe
● New memory contains garbage values
Decreasing size
● Extra data is lost
● Memory size is reduced
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr, n, i, new_n;
// Step 1: Read size
printf("Enter number of elements: ");
scanf("%d", &n);
// Step 2: Allocate memory using malloc
arr = (int *) malloc(n * sizeof(int));
// Step 3: Check memory allocation
if (arr == NULL) {
printf("Memory allocation failed");
return 1;
}
// Step 4: Read elements
printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// Step 5: Display elements
printf("Elements entered:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
// Step 6: Reallocate memory
printf("\nEnter new size: ");
scanf("%d", &new_n);
arr = (int *) realloc(arr, new_n * sizeof(int));
Geetha N, Dept of CSE BMSCE
// Step 7: Check reallocation
if (arr == NULL) {
printf("Memory reallocation failed");
return 1;
}
// Step 8: Read new elements if size increased
if (new_n > n) {
printf("Enter %d more elements:\n", new_n - n);
for (i = n; i < new_n; i++) {
scanf("%d", &arr[i]);
}
}
printf("Final array elements:\n"); // Step 9: Display final elements
for (i = 0; i < new_n; i++) {
printf("%d ", arr[i]);
}
free(arr); // Step 10: Free memory
arr = NULL;
return 0;
}
Enter number of elements: 3
Enter 3 elements:
10 20 30
Enter new size: 5
Enter 2 more elements:
40 50
Elements entered:
10 20 30
Final array elements:
10 20 30 40 50
free() – Deallocate Memory
free() releases the memory previously allocated using malloc() or calloc() back to the system.
Syntax —- free(ptr);
● Prevents memory leak
● Pointer becomes dangling after free()
● Best practice: set pointer to NULL after freeing
Geetha N, Dept of CSE BMSCE
Example using free()
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p;
p = (int *) malloc(sizeof(int));
*p = 100;
printf("Value = %d\n", *p);
free(p);
p = NULL;
return 0;
}
Output
Value = 100
Difference between malloc() and calloc()
Feature malloc() calloc()
Initialization No (garbage) Yes (0)
Arguments 1 2
Memory type Single block Multiple blocks
Speed Faster Slightly slower
Geetha N, Dept of CSE BMSCE