What is a Function & Why Use One?
A function is a named, reusable block of code. Instead of writing the same logic 10 times, write it once as a function and call it whenever needed.
- Reusability — write once, use many times
- Readability —
calculateArea()is clearer than raw formulas everywhere - Maintainability — fix a bug in one place, fixed everywhere
- Testing — test each function independently
Function anatomy — every part explained
what it gives back
what you call it
data passed in
what it does
#include <stdio.h> // Function 1: returns sum of two ints int add(int a, int b) { return a + b; } // Function 2: prints a greeting — returns nothing (void) void greet(char name[]) { printf("Hello, %s!\n", name); } // Function 3: returns larger of two numbers int maxOf(int x, int y) { if (x > y) return x; return y; } int main() { int result = add(8, 5); // call add, store result printf("8 + 5 = %d\n", result); // 13 greet("Ananta"); // call greet printf("Max = %d\n", maxOf(14, 9)); // 14 return 0; }
8 + 5 = 13 Hello, Ananta! Max = 14
void as the return type and omit the return statement (or write return; alone).
Parameters & Return Types — Passing Data
Parameters are the inputs a function receives. Return type is the type of value it gives back. C passes parameters by value — the function gets a copy, not the original.
| Return Type | What it Means | Example |
|---|---|---|
| void | Returns nothing | void printMenu() |
| int | Returns a whole number | int square(int n) |
| float | Returns a decimal | float average(float a, float b) |
| double | Returns precise decimal | double area(double r) |
| char | Returns a character | char getGrade(int marks) |
#include <stdio.h> // Returns char grade based on int marks char getGrade(int marks) { if (marks >= 90) return 'A'; if (marks >= 75) return 'B'; if (marks >= 50) return 'C'; return 'F'; } // Returns area of circle using double double circleArea(double radius) { return 3.14159 * radius * radius; } // Multiple parameters — returns average float average(float a, float b, float c) { return (a + b + c) / 3.0; } int main() { printf("Grade for 85: %c\n", getGrade(85)); printf("Area of r=5: %.2f\n", circleArea(5.0)); printf("Average: %.1f\n", average(80, 90, 70)); return 0; }
Grade for 85: B Area of r=5: 78.54 Average: 80.0
int x to a function and change it inside, the original x is NOT changed. The function works on a copy. To change the original, you must pass a pointer (covered in Day 3).
Scope — Where Variables Live
Scope defines where a variable can be accessed. In C there are two kinds:
- Local variable — declared inside a function, only visible inside that function. Destroyed when the function returns.
- Global variable — declared outside all functions, visible everywhere in the file. Lives as long as the program runs.
Scope — where each variable is visible
#include <stdio.h> int count = 0; // GLOBAL — visible in all functions void increment() { count++; // can access global count int local = 99; // LOCAL — only inside increment() printf("count=%d, local=%d\n", count, local); } int main() { int x = 10; // LOCAL to main increment(); // count becomes 1 increment(); // count becomes 2 increment(); // count becomes 3 printf("Global count = %d\n", count); printf("Local x = %d\n", x); // printf("%d", local); ERROR — local not visible here! return 0; }
Function Prototypes — Declare Before Using
C reads code top to bottom. If you call a function before it is defined, the compiler complains. A prototype is a one-line declaration at the top that tells the compiler "this function exists and here is its signature — I'll define it later."
#include <stdio.h> // PROTOTYPES — declared at top, defined below main int square(int n); double power(double base, int exp); int main() { printf("5 squared = %d\n", square(5)); // 25 printf("2^10 = %.0f\n", power(2.0, 10)); // 1024 return 0; } // DEFINITIONS — below main, compiler already knows about them int square(int n) { return n * n; } double power(double base, int exp) { double result = 1.0; for (int i = 0; i < exp; i++) result *= base; return result; }
main(), no prototype is needed. Prototypes are essential only when functions are defined after main() or in separate files.
Recursion — A Function Calling Itself
Recursion is when a function calls itself. Every recursive function needs two things: a base case (when to stop) and a recursive case (the call to itself with a smaller input). Without the base case, it recurses forever and crashes — stack overflow.
#include <stdio.h> // Factorial: 5! = 5 × 4 × 3 × 2 × 1 = 120 int factorial(int n) { if (n == 0 || n == 1) // BASE CASE — stop here return 1; return n * factorial(n - 1); // RECURSIVE CASE } // Sum: 1 + 2 + 3 + ... + n int sumN(int n) { if (n == 0) return 0; // BASE CASE return n + sumN(n - 1); // RECURSIVE CASE } int main() { printf("5! = %d\n", factorial(5)); // 120 printf("Sum 1-10 = %d\n", sumN(10)); // 55 return 0; }
factorial(5)
→ 5 × factorial(4)
→ 4 × factorial(3)
→ 3 × factorial(2)
→ 2 × factorial(1)
→ returns 1 ← BASE CASE reached
→ 2 × 1 = 2
→ 3 × 2 = 6
→ 4 × 6 = 24
→ 5 × 24 = 120 ✓
Quick Quiz
A function with return type void means:
You pass int x = 5 to a function and change it inside. What happens to the original x?
A local variable declared inside a function is:
What is a function prototype?
What is the base case in recursion?
Lesson Checklist
- I understand the 4 parts of a function: return type, name, parameters, body
- I can write a function that returns int, float, char, or void
- I understand C passes parameters by value (copies)
- I know the difference between local and global variables
- I know why to prefer local variables over global
- I understand function prototypes and when they are needed
- I can write a recursive function with a base case and recursive case
- I understand what stack overflow means in recursion
- I completed the quiz
Day 7 Preview
- 🧵 Strings deep dive — fgets, string.h, custom functions Day 7
- 📐 2D Arrays — matrices, rows & columns Day 7
- 🔗 Arrays & Functions — passing arrays to functions Day 7
- 🏗️ Structures (struct) — custom data types Day 7