Chapter 10: User-Defined Functions
- LO 10.1: Understand the need for user-defined functions
- LO 10.2: Define and call functions with various categories
- LO 10.3: Work with function arguments and return values
- LO 10.4: Implement recursion and nesting of functions
- LO 10.5: Pass arrays and strings to functions
- LO 10.6: Understand scope, visibility, and lifetime of variables
10.1 Introduction to Functions
Functions are self-contained blocks of code that perform a particular task. They are the building blocks of C programs and enable modular programming.
Top-down Modular Programming
┌─────────────────────────────────────┐
│ MAIN PROGRAM │
└─────────┬───────────────┬───────────┘
│ │
┌─────────▼─────────┐ ┌───▼──────────┐
│ Function 1 │ │ Function 2 │
└─────────┬─────────┘ └───────┬──────┘
│ │
┌─────────▼─────────┐ ┌───────▼──────┐
│ Function 1.1 │ │ Function 2.1 │
└───────────────────┘ └──────────────┘
Fig. 10.1: Top-down modular programming using functions
Advantages of using functions:
- It facilitates top-down modular programming
- The length of a source program can be reduced by using functions
- It is easy to locate and isolate faulty functions
- A function may be used by many other programs
10.2 A Multi-Function Program
📝 Worked-Out Problem 10.1
Simple program with multiple functions:
#include <stdio.h>
void printline(void) {
int i;
for (i = 1; i <= 35; i++)
printf("-");
printf("\n");
}
int main() {
printline();
printf("This illustrates the use of C functions\n");
printline();
return 0;
}
-----------------------------------
This illustrates the use of C functions
-----------------------------------
10.3 Elements of User-Defined Functions
Three elements are needed to use a function:
- Function definition: The actual code of the function
- Function call: Invoking the function
- Function declaration (prototype): Telling the compiler about the function
Function Definition Format
return_type function_name(parameter list)
{
local variable declarations;
executable statements;
return statement;
}
Function Header Components
- Return type: Type of value returned (defaults to int if omitted, void if nothing returned)
- Function name: Valid C identifier
- Parameter list: Variables receiving data from calling function (formal parameters)
Function Body
- Local declarations
- Function statements
- return statement
The return Statement
return; // No value returned return expression; // Returns value of expression
Function Prototype
return_type function_name(parameter list); // With parameter names return_type function_name(type1, type2, ...); // Without parameter names
int and takes any number of arguments. Always provide prototypes to avoid errors.
10.4 Category of Functions
Category 1: No arguments, no return values
📝 Worked-Out Problem 10.2
Functions with no arguments and no return values:
#include <stdio.h>
void printline(char c) {
int i;
for (i = 1; i <= 35; i++)
printf("%c", c);
printf("\n");
}
void value(void) {
int year, period;
float inrate, sum, principal;
printf("Principal amount: ");
scanf("%f", &principal);
printf("Interest rate: ");
scanf("%f", &inrate);
printf("Period: ");
scanf("%d", &period);
sum = principal;
year = 1;
while (year <= period) {
sum = sum * (1 + inrate);
year++;
}
printf("Total amount = %.2f\n", sum);
}
int main() {
char ch = '=';
printline(ch);
value();
printline('*');
return 0;
}
Category 2: Arguments but no return values
📝 Worked-Out Problem 10.3
One-way data communication (arguments, no return):
#include <stdio.h>
void printline(char ch, int len) {
int i;
for (i = 1; i <= len; i++)
printf("%c", ch);
printf("\n");
}
void value(float p, float r, int n) {
int year;
float sum;
sum = p;
year = 1;
while (year <= n) {
sum = sum * (1 + r);
year++;
}
printf("Total amount = %.2f\n", sum);
}
int main() {
float principal, inrate;
int period;
printf("Principal amount: ");
scanf("%f", &principal);
printf("Interest rate: ");
scanf("%f", &inrate);
printf("Period: ");
scanf("%d", &period);
printline('Z', 40);
value(principal, inrate, period);
printline('C', 40);
return 0;
}
Category 3: Arguments with return values
📝 Worked-Out Problem 10.4
Two-way data communication:
#include <stdio.h>
void printline(char ch, int len) {
int i;
for (i = 1; i <= len; i++)
printf("%c", ch);
printf("\n");
}
float value(float p, float r, int n) {
int year;
float sum;
sum = p;
year = 1;
while (year <= n) {
sum = sum * (1 + r);
year++;
}
return sum; // Return the computed value
}
int main() {
float principal, inrate, amount;
int period;
printf("Principal amount: ");
scanf("%f", &principal);
printf("Interest rate: ");
scanf("%f", &inrate);
printf("Period: ");
scanf("%d", &period);
printline('*', 52);
amount = value(principal, inrate, period);
printf("Total amount = %.2f\n", amount);
printline('=', 52);
return 0;
}
****************************************************
Total amount = 1610.51
====================================================
Returning Float Values
📝 Worked-Out Problem 10.5
Function returning float/double:
#include <stdio.h>
double power(int x, int n) {
int i;
double result = 1.0;
for (i = 1; i <= n; i++)
result *= x;
return result;
}
int main() {
int x, n;
printf("Enter x and n: ");
scanf("%d %d", &x, &n);
printf("%d to the power %d = %.0f\n", x, n, power(x, n));
return 0;
}
Enter x and n: 5 4
5 to the power 4 = 625
Category 4: No arguments but returns a value
int get_number(void) {
int num;
printf("Enter a number: ");
scanf("%d", &num);
return num;
}
10.5 Nesting of Functions
C permits nesting of functions freely. A function can call another function, which can call another, and so on.
📝 Worked-Out Problem 10.6
Nested function calls:
#include <stdio.h>
int difference(int a, int b) {
return (a - b);
}
float ratio(int a, int b, int c) {
int diff = difference(b, c);
if (diff != 0)
return (float)a / diff;
else
return 0.0;
}
int main() {
int a, b, c;
float result;
printf("Enter three numbers: ");
scanf("%d %d %d", &a, &b, &c);
result = ratio(a, b, c);
if (result != 0.0)
printf("a/(b-c) = %.2f\n", result);
else
printf("Division by zero\n");
return 0;
}
Enter three numbers: 10 8 3
a/(b-c) = 2.00
10.6 Recursion
Recursion is a special case where a function calls itself.
📝 Worked-Out Problem 10.7
Factorial using recursion:
#include <stdio.h>
int factorial(int n) {
if (n == 0 || n == 1)
return 1;
else
return n * factorial(n - 1);
}
int main() {
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("Factorial of %d = %d\n", num, factorial(num));
return 0;
}
Enter a number: 5
Factorial of 5 = 120
How it works for factorial(4):
factorial(4) = 4 * factorial(3)
= 4 * 3 * factorial(2)
= 4 * 3 * 2 * factorial(1)
= 4 * 3 * 2 * 1
= 24
📝 Worked-Out Problem 10.8
Fibonacci series using recursion:
#include <stdio.h>
int fibonacci(int n) {
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return fibonacci(n-1) + fibonacci(n-2);
}
int main() {
int n, i;
printf("Enter number of terms: ");
scanf("%d", &n);
printf("Fibonacci series: ");
for (i = 0; i < n; i++)
printf("%d ", fibonacci(i));
printf("\n");
return 0;
}
Enter number of terms: 10
Fibonacci series: 0 1 1 2 3 5 8 13 21 34
10.7 Passing Arrays to Functions
One-Dimensional Arrays
📝 Worked-Out Problem 10.9
Passing arrays to functions:
#include <stdio.h>
#include <math.h>
float mean(float arr[], int n) {
float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += arr[i];
return sum / n;
}
float std_dev(float arr[], int n) {
float m = mean(arr, n);
float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += (arr[i] - m) * (arr[i] - m);
return sqrt(sum / n);
}
int main() {
float values[100];
int n, i;
printf("Enter number of elements: ");
scanf("%d", &n);
printf("Enter %d values:\n", n);
for (i = 0; i < n; i++)
scanf("%f", &values[i]);
printf("Mean = %.2f\n", mean(values, n));
printf("Standard Deviation = %.2f\n", std_dev(values, n));
return 0;
}
Rules for Passing Arrays
- The function must be called by passing only the name of the array.
- In the function definition, the formal parameter must be declared as an array type (size optional).
- The function prototype must show that the argument is an array.
- Changes made to array elements in the function affect the original array (call by reference).
Two-Dimensional Arrays
float average(int rows, int cols, int matrix[][cols]) {
int i, j, sum = 0;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
sum += matrix[i][j];
return (float)sum / (rows * cols);
}
10.8 Searching and Sorting with Functions
📝 Worked-Out Problem 10.10
Linear search using functions:
#include <stdio.h>
int linear_search(int arr[], int n, int key) {
int i;
for (i = 0; i < n; i++) {
if (arr[i] == key)
return i;
}
return -1;
}
int main() {
int arr[100], n, key, pos, i;
printf("Enter size of array: ");
scanf("%d", &n);
printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++)
scanf("%d", &arr[i]);
printf("Enter element to search: ");
scanf("%d", &key);
pos = linear_search(arr, n, key);
if (pos != -1)
printf("%d found at position %d\n", key, pos);
else
printf("%d not found\n", key);
return 0;
}
📝 Worked-Out Problem 10.11
Bubble sort using functions:
#include <stdio.h>
void bubble_sort(int arr[], int n) {
int i, j, temp;
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main() {
int arr[100], n, i;
printf("Enter size of array: ");
scanf("%d", &n);
printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++)
scanf("%d", &arr[i]);
bubble_sort(arr, n);
printf("Sorted array:\n");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
10.9 Scope, Visibility, and Lifetime of Variables
Storage Classes
| Storage Class | Scope | Lifetime | Initialization |
|---|---|---|---|
auto |
Local to block | Within block | Garbage (uninitialized) |
register |
Local to block | Within block | Garbage |
static |
Local to block | Entire program | Zero |
extern |
Global | Entire program | Zero |
Automatic Variables (auto)
void function() {
int x; // auto by default
auto int y; // explicitly auto
x = 10; // created when function called
// destroyed when function exits
}
📝 Worked-Out Problem 10.12
Working of automatic variables:
#include <stdio.h>
void function1() {
int m = 10;
printf("function1: m = %d\n", m);
}
void function2() {
int m = 100;
printf("function2: m = %d\n", m);
function1();
}
int main() {
int m = 1000;
printf("main: m = %d\n", m);
function2();
return 0;
}
main: m = 1000
function2: m = 100
function1: m = 10
External (Global) Variables
int global_var; // Global variable
void function1() {
global_var = 100; // Can access global
}
void function2() {
global_var = 200; // Can modify global
}
📝 Worked-Out Problem 10.13
Properties of global variables:
#include <stdio.h>
int x = 10; // Global variable
void function1() {
x = x + 5;
printf("function1: x = %d\n", x);
}
void function2() {
int x = 50; // Local variable hides global
printf("function2: local x = %d\n", x);
x = x + 10;
printf("function2: local x after = %d\n", x);
}
void function3() {
printf("function3: global x = %d\n", x);
}
int main() {
printf("main: x = %d\n", x);
function1();
function2();
function3();
return 0;
}
main: x = 10
function1: x = 15
function2: local x = 50
function2: local x after = 60
function3: global x = 15
Static Variables
📝 Worked-Out Problem 10.14
Static variables retain values between calls:
#include <stdio.h>
void stat(void) {
static int x = 0; // Initialized only once
x++;
printf("x = %d\n", x);
}
int main() {
stat(); // x = 1
stat(); // x = 2
stat(); // x = 3
return 0;
}
x = 1
x = 2
x = 3
Register Variables
register int counter; // Request to store in CPU register
External Declaration (extern)
// File1.c int global_var = 100; // File2.c extern int global_var; // Use variable from File1.c
Important Points to Remember
- A function that returns a value can be used in expressions like any other C variable.
- A function that returns a value cannot be used as a stand-alone statement.
- It is a syntax error if the types in the declaration and function definition do not match.
- A
returnstatement is required if the return type is anything other thanvoid. - If a function has no parameters, the parameter list must be declared as
void. - Defining a function within another function is not allowed.
- Functions return integer value by default.
- Pass by value is the default; pass by address is used to modify calling function's variables.
Chapter Exercises
Review Questions
- State true or false:
a) Any name can be used as a function name.
b) A function without areturnstatement is illegal.
c) The return type of a function isintby default.
d) When variable values are passed to functions, a copy of them is created.
e) A function can be defined within themainfunction.
f) C functions can return only one value under their function name. - What is prototyping? Why is it necessary?
- Distinguish between actual and formal arguments.
- What is the output of:
int x = 5, y = 10; printf("%d", (x > y) ? x : y);
Multiple Choice Questions
- Which of the following is true while passing an array to a function?
a) The function is called by passing the array name without brackets
b) The size of the array is not required in the formal parameter list
c) The function prototype must show that the argument is an array
d) All of the above - Which of the following is true about automatic variables?
a) They are declared inside a function
b) They are created when the function is called and destroyed when it exits
c) A variable without storage class specification is auto by default
d) All of the above - For which type of variable does the value persist till the end of the program?
a) auto
b) static
c) register
d) None - If the number and type of arguments in a function declaration and definition do not match:
a) The type in the definition is considered
b) The type in the declaration is considered
c) A compiler error is generated
d) None
Debugging Exercises
Find errors in the following function definitions:
void printline() // Missing semicolon?
{
printf("Hello");
}
int sum(int a, b) // Parameter b missing type
{
return a + b;
}
float average(x, y) // Missing parameter types
{
return (x + y) / 2.0;
}
void display() {
printf("Hello");
return 5; // Returning value from void function
}
Programming Exercises
- Write a function
exchangeto interchange the values of two variables (using pointers). - Write a function to evaluate an n-order polynomial using Horner's method.
- Write a recursive function to generate and print the first n Fibonacci numbers.
- Write a function
primethat returns 1 if its argument is prime, 0 otherwise. - Write a function that converts all lowercase characters in a string to uppercase.
- Develop a top-down modular program to implement a calculator with functions for add, subtract, multiply, divide.
- Write a function to find the largest element of an m×n matrix.
- Write functions to perform string operations: copy, compare, concatenate (without using library functions).
- Write a recursive function to compute the GCD of two numbers.
- Write a function
leapthat receives a year and returns whether it's a leap year.
Interview Questions
- Is it possible to execute instructions after the
mainfunction has ended? - What is the difference between formal arguments and actual arguments?
- What is the difference between 'call by value' and 'call by reference'?
- Write a recursive function to find the GCD of two numbers.
- What is the default return type of a function defined without a return type?
- What will be the output of:
int a = 10, b = 20; a = a++ + ++b; b = ++a + b++; printf("%d %d", a, b);
Case Study: Calculation of Area Under a Curve
📝 Case Study: Computing area using trapezoidal rule
#include <stdio.h>
float f(float x) {
return x * x + 1; // Function f(x) = x² + 1
}
float area(float a, float b, int n) {
float h = (b - a) / n;
float sum = 0.5 * (f(a) + f(b));
int i;
for (i = 1; i < n; i++)
sum += f(a + i * h);
return sum * h;
}
int main() {
float lower, upper;
int intervals;
printf("Enter lower limit: ");
scanf("%f", &lower);
printf("Enter upper limit: ");
scanf("%f", &upper);
printf("Enter number of trapezoids: ");
scanf("%d", &intervals);
printf("Area under f(x) = x² + 1 from %.2f to %.2f = %.4f\n",
lower, upper, area(lower, upper, intervals));
return 0;
}
Enter lower limit: 0
Enter upper limit: 3
Enter number of trapezoids: 100
Area under f(x) = x² + 1 from 0.00 to 3.00 = 12.0000
Note: The actual area (by integration) is 12.0. More trapezoids give better accuracy.