Day 6: Functions#

Overview#

Functions allow us to write reusable blocks of code. Today we’ll learn how to declare, define, and call functions, and understand variable scope and lifetime.

What We’ll Learn Today#

  • What are functions and why they’re important
  • Function declaration (prototype)
  • Function definition
  • Function calls
  • Return types and parameters
  • Variable scope and lifetime
  • Passing arguments by value

Why Functions?#

Functions help us:

  • Reuse code: Write once, use multiple times
  • Organize code: Break complex problems into smaller pieces
  • Maintain code: Easier to find and fix bugs
  • Test code: Test each part independently

Function Basics#

Function Structure#

returnType functionName(parameter1, parameter2, ...) {
    // Function body
    // Code to execute
    return value;  // If returnType is not void
}

Simple Example#

#include <stdio.h>

// Function declaration (prototype)
void greet();

// Main function
int main() {
    greet();  // Function call
    return 0;
}

// Function definition
void greet() {
    printf("Hello, World!\n");
}

Output:

Hello, World!

Function Declaration (Prototype)#

Tells the compiler about the function before it’s defined:

returnType functionName(parameterTypes);

Examples#

void sayHello();
int add(int, int);
float calculateArea(float);

Why needed? The compiler needs to know the function exists and what it expects before main() calls it.


Parameters and Return Types#

Function with Parameters#

Parameters are variables passed to the function:

#include <stdio.h>

void printNumber(int num) {
    printf("Number: %d\n", num);
}

int main() {
    printNumber(42);
    printNumber(100);
    return 0;
}

Output:

Number: 42
Number: 100

Multiple Parameters#

#include <stdio.h>

void printSum(int a, int b) {
    printf("%d + %d = %d\n", a, b, a + b);
}

int main() {
    printSum(5, 3);
    printSum(10, 20);
    return 0;
}

Output:

5 + 3 = 8
10 + 20 = 30

Function with Return Type#

#include <stdio.h>

int add(int a, int b) {
    int sum = a + b;
    return sum;  // Return the result
}

int main() {
    int result = add(5, 3);
    printf("Result: %d\n", result);
    return 0;
}

Output:

Result: 8

Complete Function Template#

#include <stdio.h>

// Prototype
int multiply(int, int);

int main() {
    int x = 5, y = 4;
    int product = multiply(x, y);
    printf("Product: %d\n", product);
    return 0;
}

// Definition
int multiply(int a, int b) {
    return a * b;
}

Practical Examples#

Example 1: Temperature Converter#

#include <stdio.h>

float celsiusToFahrenheit(float celsius) {
    return (celsius * 9/5) + 32;
}

float fahrenheitToCelsius(float fahrenheit) {
    return (fahrenheit - 32) * 5/9;
}

int main() {
    float temp_c = 25;
    float temp_f = 77;

    printf("%.1f C = %.1f F\n", temp_c, celsiusToFahrenheit(temp_c));
    printf("%.1f F = %.1f C\n", temp_f, fahrenheitToCelsius(temp_f));

    return 0;
}

Example 2: Calculator Functions#

#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
double divide(double a, double b) {
    if (b != 0)
        return a / b;
    return 0;
}

int main() {
    printf("10 + 5 = %d\n", add(10, 5));
    printf("10 - 5 = %d\n", subtract(10, 5));
    printf("10 * 5 = %d\n", multiply(10, 5));
    printf("10 / 5 = %.2f\n", divide(10, 5));

    return 0;
}

Example 3: Checking Prime Numbers#

#include <stdio.h>

int isPrime(int num) {
    if (num < 2)
        return 0;

    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0)
            return 0;
    }
    return 1;
}

int main() {
    int number;

    printf("Enter a number: ");
    scanf("%d", &number);

    if (isPrime(number)) {
        printf("%d is prime\n", number);
    } else {
        printf("%d is not prime\n", number);
    }

    return 0;
}

Variable Scope and Lifetime#

Local Variables#

Declared inside a function, exist only within that function:

#include <stdio.h>

void function1() {
    int x = 10;  // Local to function1
    printf("In function1: x = %d\n", x);
}

void function2() {
    int x = 20;  // Different x, local to function2
    printf("In function2: x = %d\n", x);
}

int main() {
    function1();  // x = 10
    function2();  // x = 20
    // printf("%d\n", x);  // ERROR: x not defined here

    return 0;
}

Global Variables#

Declared outside all functions, accessible everywhere:

#include <stdio.h>

int globalX = 100;  // Global variable

void displayGlobal() {
    printf("Global X: %d\n", globalX);
}

int main() {
    printf("Global X: %d\n", globalX);
    displayGlobal();

    globalX = 200;
    displayGlobal();  // Shows new value

    return 0;
}

Note: While possible, excessive use of global variables is poor practice. Use local variables when possible.

Variable Lifetime#

#include <stdio.h>

void counter() {
    int count = 0;  // Created each time function is called
    count++;
    printf("Count: %d\n", count);  // Always prints 1
}

int main() {
    counter();  // Prints: Count: 1
    counter();  // Prints: Count: 1
    counter();  // Prints: Count: 1

    return 0;
}

Pass by Value#

When you pass a variable to a function, C passes a copy of the value:

#include <stdio.h>

void increment(int num) {
    num++;  // Increment copy, not original
}

int main() {
    int x = 5;
    increment(x);
    printf("x = %d\n", x);  // Still 5, not 6

    return 0;
}

The original x is NOT changed because we passed a copy.


Practical Program: Student Grade System#

#include <stdio.h>

float calculateAverage(int score1, int score2, int score3) {
    return (score1 + score2 + score3) / 3.0;
}

char getGrade(float average) {
    if (average >= 90) return 'A';
    if (average >= 80) return 'B';
    if (average >= 70) return 'C';
    if (average >= 60) return 'D';
    return 'F';
}

void displayResult(const char* name, float average, char grade) {
    printf("\nName: %s\n", name);
    printf("Average: %.2f\n", average);
    printf("Grade: %c\n", grade);
}

int main() {
    int score1, score2, score3;
    float average;
    char grade;

    printf("Enter name: ");
    char name[50];
    scanf("%s", name);

    printf("Enter 3 scores: ");
    scanf("%d %d %d", &score1, &score2, &score3);

    average = calculateAverage(score1, score2, score3);
    grade = getGrade(average);

    displayResult(name, average, grade);

    return 0;
}

Common Function Patterns#

Void Function (No Return)#

void printLine() {
    printf("================\n");
}

// Call it
printLine();

Boolean-like Functions#

int isEven(int num) {
    return num % 2 == 0;  // Returns 1 or 0
}

if (isEven(10)) {
    printf("10 is even\n");
}

Calculation Function#

double calculateArea(double radius) {
    const double PI = 3.14159;
    return PI * radius * radius;
}

Practice Exercises#

Exercise 1: Basic Functions#

Write functions for:

  • Calculate factorial
  • Check if number is even/odd
  • Convert kilometers to miles

Exercise 2: Grade System#

Create functions for:

  • Input student scores
  • Calculate average
  • Determine grade
  • Display results

Exercise 3: Utility Functions#

Write a program with functions to:

  • Find maximum of two numbers
  • Find minimum of three numbers
  • Check if character is vowel

Summary#

✅ Understood function structure
✅ Created function prototypes
✅ Defined functions with return types
✅ Passed parameters to functions
✅ Understood variable scope
✅ Learned pass by value
✅ Created practical function-based programs

Key Points to Remember#

  1. Declare function prototype before main() or before first use
  2. Match parameter count and types when calling
  3. Always check return value when division is involved
  4. Use local variables by default
  5. Functions should do one thing well
  6. Give functions descriptive names

Next Steps#

Tomorrow we’ll learn about arrays and strings - collections of data!

→ Continue to Day 7

← Back to Day 5