IT232 C Programming

C ProgrammingUnit 612 min read

Functions in C: Definition, Types, Recursion, and Library Functions

Unit 6 of C Programming covers the concept of functions—how to define, declare, call, and use them in programs, including recursive functions, library functions, and their role in modular programming. Learn syntax, scope rules, and real-world applications like string manipulation and mathematical computations.

TAKEAWAYS:

  • Functions in C enable modular programming by breaking code into reusable blocks with a single responsibility.
  • A function must be declared before use (or defined earlier) and can return a value or operate via parameters.
  • Recursion solves problems by calling a function within itself, but requires a base case to terminate.
  • Library functions (e.g., strlen(), malloc()) provide pre-built functionality for common tasks like string handling or memory allocation.
  • Scope rules determine where variables are accessible: local (inside function), global (entire program), or static (retains value between calls).
  • Functions like printf(), exit(), and graphics functions (e.g., circle()) are essential for output, program termination, and visualization.

1. Introduction to Functions

A function is a block of code that performs a specific task. It is reusable, modular, and improves code readability. Functions can:

  • Take input (parameters/arguments).
  • Perform operations.
  • Return output (optional).

Syntax of a Function

return_type function_name(parameter_list) {
    // Function body
    return value; // Optional, if return_type is not void
}

Example:

int add(int a, int b) {
    return a + b;
}

Types of Functions

Type Description Example
User-defined Created by the programmer for custom tasks. int factorial(int n)
Library Predefined in C standard libraries (e.g., stdio.h, string.h). strlen(char *str)
Recursive A function calling itself to solve problems (e.g., factorial, Fibonacci). int fib(int n)
Void Does not return a value (return_type is void). void greet()

2. Defining and Calling Functions

510max(5, 10)8greatest(5, 10, 8)
Call tree showing nested function calls for greatest(5, 10, 8) with intermediate max(5, 10) evaluation

Step-by-Step Process

  1. Declaration: Inform the compiler about the function’s existence (optional if defined before use).
    int max(int a, int b); // Declaration (prototype)
    
  2. Definition: Write the function’s logic.
    int max(int a, int b) {
        return (a > b) ? a : b;
    }
    
  3. Calling: Use the function in main() or other functions.
    int result = max(5, 10); // Call
    printf("Max: %d", result);
    

Example: Find the Greatest of Three Numbers

Program:

#include <stdio.h>

```figure
{"type":"tree","root":{"v":"max(a, b, c)","children":[{"v":"max(a, b)","children":[{"v":"a"},{"v":"b"}]},{"v":"c"}]},"caption":"Call tree for finding the greatest of three numbers using nested max calls"}

int greatest(int a, int b, int c) { if (a > b && a > c) return a; else if (b > a && b > c) return b; else return c; }

int main() { int x = 5, y = 10, z = 8; printf("Greatest: %d", greatest(x, y, z)); return 0; }

**Output:**

Greatest: 10

Trace Table:

Step greatest(5, 10, 8) Return Value
1 5 > 10 && 5 > 8 → 0 Check b
2 10 > 5 && 10 > 8 → 1 Return 10

3. Recursive Functions

A recursive function calls itself to solve smaller instances of the same problem. Key Components:

  • Base Case: Terminates recursion (e.g., factorial(0) = 1).
  • Recursive Case: Breaks the problem into smaller subproblems.
stateDiagram-v2
	state "factorial(5)" as f5
	state "factorial(4)" as f4
	state "factorial(3)" as f3
	state "factorial(2)" as f2
	state "factorial(1)" as f1
	state "factorial(0)" as f0

	f5 --> f4 : 5 * 
	f4 --> f3 : 4 * 
	f3 --> f2 : 3 * 
	f2 --> f1 : 2 * 
	f1 --> f0 : 1 * 
	f0 --> f1 : return 1

	class f5,f4,f3,f2,f1 recursive
	class f0 fill:#bbf,stroke:#333
State diagram of recursive calls for factorial(5) showing the call stack and return path

Example: Factorial Using Recursion

Program:

#include <stdio.h>

int factorial(int n) {
    if (n == 0) // Base case
        return 1;
    else
        return n * factorial(n - 1); // Recursive call
}

int main() {
    int num = 5;
    printf("Factorial of %d: %d", num, factorial(num));
    return 0;
}

Output:

Factorial of 5: 120

Trace Table:

Step factorial(5) Recursive Calls Return Value
1 5 * factorial(4) factorial(4) → 4 * factorial(3) 120
2 factorial(3) → 3 * factorial(2)
3 factorial(2) → 2 * factorial(1)
4 factorial(1) → 1 * factorial(0)
5 factorial(0) → 1 (base case)

Visualization of Recursion Stack:

factorial(5)factorial(4)factorial(3)factorial(2)factorial(1)factorial(0) -> 1TOP
Recursion stack state at maximum depth for factorial(5)

4. Library Functions

C provides built-in functions in libraries (e.g., stdio.h, string.h). Common examples:

0NepalKathmandu1IndiaMumbai2ChinaBeijing3USAWashington
Hash table storing country-capital pairs with h(key) = key[0] mod 4 (simplified for demonstration)
Function Library Purpose Example
printf() stdio.h Print formatted output. printf("Sum: %d", sum);
scanf() stdio.h Read input from the user. scanf("%d", &num);
strlen() string.h Return the length of a string. len = strlen("hello");
strcpy() string.h Copy a string to another. strcpy(dest, src);
malloc() stdlib.h Allocate memory dynamically. ptr = malloc(size);
exit() stdlib.h Terminate the program. exit(0);
circle() graphics.h Draw a circle (graphics). circle(100, 100, 50);

Example: String Length Without strlen()

Program:

#include <stdio.h>

int my_strlen(char str[]) {
    int len = 0;
    while (str[len] != '\0') {
        len++;
    }
    return len;
}

int main() {
    char name[] = "Nepal";
    printf("Length: %d", my_strlen(name));
    return 0;
}

Output:

Length: 5

Trace Table:

Step name[] len Condition str[len] != '\0' Action
1 'N' 0 'N' != '\0' → 1 len = 1
2 'e' 1 'e' != '\0' → 1 len = 2
3 'p' 2 'p' != '\0' → 1 len = 3
4 'a' 3 'a' != '\0' → 1 len = 4
5 'l' 4 'l' != '\0' → 1 len = 5
6 '\0' 5 '0' == '\0' → 0 Exit loop

5. Scope of Variables

Variables can be:

  • Local: Accessible only within the function.
  • Global: Accessible throughout the program.
  • Static: Retains value between function calls.
classDiagram
	class GlobalVar {
		- int x = 10
	}
	class LocalVar {
		- int y = 20
	}
	class StaticVar {
		- int z = 30
	}

	GlobalVar --> LocalVar : accessible
	GlobalVar --> StaticVar : accessible
	LocalVar --> StaticVar : not accessible

	class Program {
		-- GlobalVar
		-- LocalVar
		-- StaticVar
	}
Variable scope relationships in a C program showing global, local, and static variable accessibility
00.250.50.751Global Variable1Local Variable0Accessible in Function?
Accessibility of variable types within a function scope

Example: Local vs. Global Variables

#include <stdio.h>

int count = 0; // Global variable

void increment() {
    int local = 10; // Local variable
    count++;
    printf("Local: %d, Global: %d\n", local, count);
}

int main() {
    increment(); // Output: Local: 10, Global: 1
    increment(); // Output: Local: 10, Global: 2
    return 0;
}

Output:

Local: 10, Global: 1
Local: 10, Global: 2

6. Functions in Graphics (Optional)

For graphics programming (e.g., using graphics.h in Turbo C), functions like:

  • circle(x, y, radius): Draw a circle at (x, y) with given radius.
  • line(x1, y1, x2, y2): Draw a line between two points.

Example: Draw a Circle

#include <graphics.h>
#include <stdio.h>

int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
    circle(200, 200, 50); // Draw circle at (200,200) with radius 50
    getch();
    closegraph();
    return 0;
}

Flowchart for Drawing a Circle:


In the Real World

  1. eSewa (Nepal):

    • Uses modular functions to handle transactions (e.g., process_payment(), validate_user()).
    • Recursion might be used in backend algorithms for fraud detection (e.g., checking nested transaction histories).
  2. Khalti (Digital Payments):

    • Library functions like encrypt_data() (from openssl) secure transactions.
    • Dynamic memory allocation (malloc()) manages variable-sized transaction records.
  3. Pathao (Ride-Hailing):

    • Recursive functions optimize route-finding (e.g., splitting a long route into smaller segments).
    • Graphics functions (draw_map()) render real-time driver locations on the app’s map.
  4. NTC (Telecom Billing):

    • User-defined functions like calculate_bill() compute charges based on usage.
    • String functions (strcpy(), strlen()) process customer names and IDs.
  5. Bank Loan Interest Calculation:

    • A bank’s system uses a recursive function to compute compound interest:
      float compound_interest(float principal, float rate, int years) {
          if (years == 0) return principal;
          else return (principal * rate) + compound_interest(principal * rate, rate, years - 1);
      }
      
    • Example: For a loan of ₹100,000 at 5% for 3 years, the function calculates:
      Year 1: ₹100,000 * 1.05 = ₹105,000
      Year 2: ₹105,000 * 1.05 = ₹110,250
      Year 3: ₹110,250 * 1.05 = ₹115,762.50
      

Exam Tip

  1. Function Syntax:

    • Always include the return type, function name, and parameters in declarations.
    • Example: int sum(int a, int b); (not sum(a, b)).
  2. Recursion:

    • Must have a base case to avoid infinite loops.
    • Example: factorial(0) = 1 is critical.
  3. Library Functions:

    • Know the header file (e.g., strlen() requires #include <string.h>).
    • Memorize common functions like printf(), scanf(), malloc().
  4. Scope Rules:

    • Local variables are reinitialized on each function call.
    • Global variables persist but can lead to unintended side effects.
  5. Graphics Functions:

    • For questions on circle() or line(), draw a flowchart showing initialization, drawing, and cleanup steps.
  6. Common Mistakes to Avoid:

    • Forgetting to return a value in non-void functions.
    • Mismatched parameters (e.g., calling max(5) when defined as max(int a, int b)).
    • Infinite recursion (missing base case).

Practice Questions for TU/PU Exams:

  1. Write a function reverse_string(char str[]) that reverses a string without using strrev().
  2. Explain the difference between pass-by-value and pass-by-reference in C functions.
  3. Draw a flowchart for a function that checks if a number is prime.
  4. How would you use malloc() to dynamically allocate an array of 10 integers?
  5. Write a recursive function to calculate the nth Fibonacci number.

Based on the TU BITM syllabus for C Programming (IT232), unit 6.

Discussion

Loading…