unit7 Functions
unit7 Functions
1. Basics of Functions
A function is a block of code designed to perform a specific task. Functions can be called multiple
times within a program to reduce redundancy and improve efficiency.
Components of a Function
1. Declaration (Prototype):
• Specifies the function name, return type, and parameters.
• Example: int add(int a, int b);
2. Definition:
• Contains the logic of the function.
• Example:
3. Call:
• Executes the function by passing arguments.
• Example: int result = add(5, 3);
2. Types of Functions
Functions in C are classified as:
1. Input/Output Functions
These functions handle standard input and output operations and are declared in <stdio.h>.
Common Functions:
Function Description Example
printf() Prints formatted data to the console. printf("Hello, World!");
scanf() Reads formatted input from the user. scanf("%d", &num);
gets() Reads a string from the user. gets(str);
puts() Writes a string to the console. puts("Hello!");
Example Code:
#include <stdio.h>
int main() {
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("You entered: %d\n", num);
return 0;
}
2. Mathematical Functions
Mathematical functions are declared in <math.h> and provide operations like square roots, powers,
trigonometric calculations, and more.
Common Functions:
Function Description Example
sqrt() Calculates the square root. sqrt(25.0) → 5.0
pow() Calculates the power. pow(2.0, 3.0) → 8.0
sin() Calculates the sine of an angle. sin(1.57)
abs() Returns the absolute value. abs(-5) → 5
Example Code:
#include <stdio.h>
#include <math.h>
int main() {
double num = 16.0;
printf("Square root of %.2f is %.2f\n", num, sqrt(num));
printf("2 raised to the power 3 is %.2f\n", pow(2, 3));
return 0;
}
3. String Functions
String handling functions are declared in <string.h> and are used for operations like copying,
concatenation, length calculation, and comparison.
Common Functions:
Function Description Example
strlen() Returns the length of a string. strlen("Hello") → 5
strcpy() Copies one string to another. strcpy(dest, src);
strcat() Concatenates two strings. strcat(str1, str2);
strcmp() Compares two strings. strcmp("abc", "def") → < 0
Example Code:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
char result[40];
Common Functions:
Function Description Example
ptr = malloc(10 *
malloc() Allocates memory dynamically. sizeof(int));
calloc() Allocates memory and initializes it to ptr = calloc(10, sizeof(int));
zero.
free() Frees allocated memory. free(ptr);
realloc() Reallocates memory to a new size. ptr = realloc(ptr, new_size);
Example Code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr, size = 5;
arr = (int *)malloc(size * sizeof(int));
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
free(arr);
return 0;
}
5. Utility Functions
Utility functions, declared in <stdlib.h>, perform tasks like conversions, random number
generation, and sorting.
Common Functions:
Function Description Example
atoi() Converts string to integer. atoi("123") → 123
atof() Converts string to float. atof("12.34") → 12.34
rand() Generates a random number. rand() % 10 → Random 0-9
qsort() Sorts an array. qsort(arr, n, sizeof(int), cmp)
Example Code:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Random number: %d\n", rand() % 100);
return 0;
}
int main() {
int a = 5, b = 10;
printf("Product: %d\n", multiply(a, b)); // Function call
return 0;
}
#include <stdio.h>
void countCalls() {
static int count = 0; // Static variable
count++;
printf("Function called %d times\n", count);
}
int main() {
countCalls();
countCalls();
return 0;
}
Output:
Function called 1 times
Function called 2 times
4. Recursion
Recursion is a technique in programming where a function calls itself directly or indirectly to solve a
problem. Recursion simplifies solving problems that can be broken down into smaller, similar sub-
problems. It is a key concept in programming and is widely used for implementing algorithms like
factorial computation, Fibonacci series, and more.
int factorial(int n) {
if (n == 0) { // Base case
return 1;
} else {
return n * factorial(n - 1); // Recursive case
}
}
int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}
Output:
Factorial of 5 is 120
Explanation:
1. For factorial(5), the function calls itself as:
• 5×factorial(4)
• 4×factorial(3)
• 3×factorial(2)
• 2×factorial(1)
• 1×factorial(0)
2. The recursion stops when the base case (n == 0) is met, returning 1.
3. The results are multiplied step by step as the function returns to its previous calls.
Types of Recursion
1. Direct Recursion
• A function calls itself directly. Example:
void directRecursion() {
printf("Direct Recursion\n");
directRecursion(); // Calls itself
}
2. Indirect Recursion
• A function calls another function, which in turn calls the original function. Example:
void functionA();
void functionB();
void functionA() {
printf("Function A\n");
functionB(); // Calls functionB
}
void functionB() {
printf("Function B\n");
functionA(); // Calls functionA
}
Advantages of Recursion
1. Simplifies the code for problems that can be divided into sub-problems.
2. Reduces the need for complex loops in certain algorithms (e.g., tree traversal, backtracking).
Disadvantages of Recursion
1. May lead to stack overflow if the base case is not defined or the recursion depth is too large.
2. Can be less efficient than iterative solutions due to repeated function calls and memory
overhead.
Applications of Recursion
1. Mathematical Computations:
• Factorial, Fibonacci series, GCD, etc.
2. Data Structures:
• Traversing trees and graphs (e.g., depth-first search).
3. Problem Solving:
• Solving puzzles like the Tower of Hanoi.
4. Divide and Conquer Algorithms:
• QuickSort, MergeSort.
Example 2: Fibonacci Series Using Recursion
The Fibonacci series is defined as:
F(n)=F(n−1)+F(n−2)
With base cases:
F(0)=0,F(1)=1
Code Example:
#include <stdio.h>
int fibonacci(int n) {
if (n == 0) {
return 0; // Base case
} else if (n == 1) {
return 1; // Base case
} else {
return fibonacci(n - 1) + fibonacci(n - 2); // Recursive case
}
}
int main() {
int n = 10;
printf("Fibonacci series up to %d terms:\n", n);
for (int i = 0; i < n; i++) {
printf("%d ", fibonacci(i));
}
return 0;
}
Output:
Fibonacci series up to 10 terms:
0 1 1 2 3 5 8 13 21 34
int main() {
int n = 3; // Number of disks
printf("Steps to solve Tower of Hanoi with %d disks:\n", n);
towerOfHanoi(n, 'A', 'C', 'B');
return 0;
}
Output:
Steps to solve Tower of Hanoi with 3 disks:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
Practice Questions
1. Write a recursive function to find the GCD of two numbers.
2. Implement a recursive function to calculate the power of a number.
3. Create a recursive function to reverse a string.
4. Write a program to traverse a binary tree using recursion.
5. Solve the Tower of Hanoi puzzle for 4 disks.
1. Pass by Value
Definition
• In pass by value, a copy of the actual argument is passed to the function.
• The function works with the copy, and any changes made to the parameter inside the function
do not affect the original argument.
Key Characteristics
1. Changes to the parameter do not impact the original variable.
2. Safer method since the original data remains unmodified.
3. Slightly slower for large data as it requires copying the value.
void modifyValue(int x) {
x = 20; // Modifying the local copy
}
int main() {
int num = 10;
modifyValue(num); // Passing by value
printf("Value of num after function call: %d\n", num); // Original value
remains unchanged
return 0;
}
Output:
Value of num after function call: 10
2. Pass by Reference
Definition
• In pass by reference, the memory address of the actual argument is passed to the function.
• The function works directly on the original data, and any changes made to the parameter affect
the original argument.
Key Characteristics
1. Changes to the parameter directly impact the original variable.
2. More efficient for large data structures as no copying is required.
3. Potentially riskier because the original data can be unintentionally altered.
Output:
Value of num after function call: 20
// Pass by Value
void passByValue(int x) {
x = 20;
printf("Inside passByValue: %d\n", x);
}
// Pass by Reference
void passByReference(int *x) {
*x = 20;
printf("Inside passByReference: %d\n", *x);
}
int main() {
int num = 10;
// Pass by Value
printf("Before passByValue: %d\n", num);
passByValue(num);
printf("After passByValue: %d\n\n", num);
// Pass by Reference
printf("Before passByReference: %d\n", num);
passByReference(&num);
printf("After passByReference: %d\n", num);
return 0;
}
Output:
Before passByValue: 10
Inside passByValue: 20
After passByValue: 10
Before passByReference: 10
Inside passByReference: 20
After passByReference: 20
Conclusion
• Pass by Value is safer and more straightforward but involves copying data, making it less
efficient for large datasets.
• Pass by Reference allows functions to directly modify original data and is more efficient for
large datasets but comes with risks of unintended side effects.
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("Sum: %d\n", calculateSum(numbers, size));
return 0;
}
Output:
Sum: 15
void increment() {
static int count = 0; // Static variable
count++;
printf("Count: %d\n", count);
}
int main() {
increment();
increment();
return 0;
}
Output:
Count: 1
Count: 2
int main() {
register int i; // Register variable
for (i = 0; i < 5; i++) {
printf("%d ", i);
}
return 0;
}
Output:
0 1 2 3 4
Conclusion
Functions in C provide modularity and reusability, making programs more organized and maintainable.
From built-in library functions to custom user-defined ones, mastering their usage is essential.
Understanding recursion, variable scope, and the nuances of passing data ensures writing efficient and
robust programs. Concepts like static and register variables add further optimization to program
behavior, making functions a critical topic in C programming for engineering students.
Practice Questions on Functions in C
1. Library Functions
Example Problem:
Write a program to find the square root of a given number using the sqrt() function from the
math.h library.
Solution:
#include <stdio.h>
#include <math.h>
int main() {
double number;
printf("Enter a number: ");
scanf("%lf", &number);
printf("Square root of %.2f is %.2f\n", number, sqrt(number));
return 0;
}
Self-Do Questions:
1. Write a program to find the length of a string using the strlen() function.
2. Use the pow() function to calculate the power of a number raised to another number.
3. Write a program to sort an array of integers using the qsort() library function.
2. User-Defined Functions
Example Problem:
Write a user-defined function to calculate the area of a rectangle.
Solution:
#include <stdio.h>
int main() {
float length, width;
printf("Enter length and width: ");
scanf("%f %f", &length, &width);
printf("Area of rectangle: %.2f\n", calculateArea(length, width)); // Function
call
return 0;
}
Self-Do Questions:
1. Write a user-defined function to find the factorial of a number.
2. Create a function to check if a number is even or odd.
3. Write a function to convert Celsius to Fahrenheit.
3. Recursion
Example Problem:
Write a recursive function to calculate the sum of numbers from 1 to n.
Solution:
#include <stdio.h>
int sum(int n) {
if (n == 0) {
return 0; // Base case
}
return n + sum(n - 1); // Recursive case
}
int main() {
int n;
printf("Enter a number: ");
scanf("%d", &n);
printf("Sum of numbers from 1 to %d is %d\n", n, sum(n));
return 0;
}
Self-Do Questions:
1. Write a recursive function to find the greatest common divisor (GCD) of two numbers.
2. Create a recursive function to reverse a given string.
3. Write a recursive function to generate the Fibonacci series up to n terms.
4. Pass by Value
Example Problem:
Write a program to demonstrate pass by value using a function that attempts to change the value of a
variable.
Solution:
#include <stdio.h>
void modifyValue(int x) {
x = 20; // Local modification
}
int main() {
int num = 10;
modifyValue(num);
printf("Value of num after function call: %d\n", num); // Original value
remains unchanged
return 0;
}
Self-Do Questions:
1. Write a program to demonstrate the behavior of a pass-by-value function using a different data
type.
2. Create a function that calculates the square of a number using pass by value.
3. Write a program to demonstrate why changes inside a pass-by-value function do not affect the
original variable.
5. Pass by Reference
Example Problem:
Write a program to demonstrate pass by reference using a function that modifies the original value of a
variable.
Solution:
#include <stdio.h>
int main() {
int num = 10;
modifyValue(&num);
printf("Value of num after function call: %d\n", num); // Modified value
return 0;
}
Self-Do Questions:
1. Write a program to swap two numbers using pass by reference.
2. Create a function to calculate the sum of two numbers using pointers.
3. Write a program to demonstrate the difference between pass by reference and pass by value.
int main() {
int numbers[] = {1, 3, 7, 0, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("Largest element: %d\n", findLargest(numbers, size));
return 0;
}
Self-Do Questions:
1. Write a function to calculate the sum of all elements in an array.
2. Create a function to reverse an array and print the reversed array.
3. Write a function to check if an array is sorted in ascending order.
void increment() {
static int count = 0; // Retains its value
count++;
printf("Count: %d\n", count);
}
int main() {
increment();
increment();
increment();
return 0;
}
Self-Do Questions:
1. Write a program to track how many times a specific function is called using a static variable.
2. Create a program to simulate a simple counter using a static variable.
3. Write a program to demonstrate the difference between static and local variables in functions.
8. Register Variables
Example Problem:
Write a program to demonstrate the use of a register variable in a loop.
Solution:
#include <stdio.h>
int main() {
register int i; // Register variable for faster access
for (i = 0; i < 5; i++) {
printf("%d ", i);
}
return 0;
}
Self-Do Questions:
1. Write a program to use a register variable for frequently accessed variables in a computation.
2. Create a program to compare the behavior of register and non-register variables.
3. Write a program to demonstrate that the address of a register variable cannot be accessed.