Study guide on functions in C.

# Functions in C

## What is a function?

A function is a named block of code that performs a specific task.

Instead of writing the same logic many times in different parts of a program, you write that logic once inside a function and call it whenever needed.

A function can:

* take input
* process something
* return a result
* do an action without returning anything

Examples of tasks a function might do:

* add two numbers
* check whether a number is even
* print a menu
* calculate a student's average
* swap values
* read data from a file

## Why do we use functions?

Functions are used to make programs:

### Easier to read

Breaking a long program into smaller named parts makes it much easier to understand.

### Easier to reuse

If a task is needed multiple times, write it once and call it many times.

### Easier to debug

If something goes wrong, you can test one function at a time instead of checking the whole program.

### Easier to maintain

Changing logic in one function updates all places that call it.

### More modular

A large problem can be split into small manageable pieces.

## Real life analogy

Think of a function like a machine.

* You give it input
* It performs a task
* It gives you output

For example:

* input: 5 and 7
* task: add the two numbers
* output: 12

Some machines only do an action and do not return anything. For example, a printer prints a page but does not return a value.

## General syntax of a function

```c
return_type function_name(parameter_list)
{
    // statements
    return value;
}
```

### Parts of this syntax

#### return_type

This tells us what type of value the function sends back.

Examples:

* `int`
* `float`
* `char`
* `void`

If the function does not return anything, use `void`.

#### function_name

This is the name used to call the function.

Examples:

* `add`
* `printMenu`
* `findMaximum`

#### parameter_list

These are inputs the function receives.

Example:

```c
int add(int a, int b)
```

Here the parameters are `int a` and `int b`.

#### function body

This is the actual code inside the braces `{ }`.

#### return statement

This sends a value back to the place where the function was called.

## Simple example

```c
#include <stdio.h>

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

int main(void)
{
    int result = add(4, 6);
    printf("%d\n", result);
    return 0;
}
```

### What happens here?

1. `main()` calls `add(4, 6)`
2. `4` is copied into parameter `a`
3. `6` is copied into parameter `b`
4. the function calculates `a + b`
5. the value `10` is returned
6. `result` stores `10`
7. `printf` prints `10`

## Function declaration, definition, and call

These three ideas are very important.

### Function declaration

Also called a prototype.

It tells the compiler:

* the function name
* the return type
* the number and type of parameters

Example:

```c
int add(int a, int b);
```

### Function definition

This is the full implementation of the function.

Example:

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

### Function call

This is when you use the function.

Example:

```c
int result = add(4, 6);
```

## Why do we need function declarations?

In C, the compiler reads code from top to bottom.

If you call a function before the compiler has seen it, the compiler needs a declaration first.

Example:

```c
#include <stdio.h>

int add(int a, int b);

int main(void)
{
    printf("%d\n", add(2, 3));
    return 0;
}

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

Without the declaration, the compiler may not know about `add` when `main` tries to call it.

## Types of functions

Functions are often classified by whether they take parameters and whether they return a value.

## Case 1: No parameters, no return value

```c
#include <stdio.h>

void greet(void)
{
    printf("Hello\n");
}

int main(void)
{
    greet();
    return 0;
}
```

This function just performs an action.

## Case 2: Parameters, no return value

```c
#include <stdio.h>

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

int main(void)
{
    printSum(3, 5);
    return 0;
}
```

This function receives input but does not return anything.

## Case 3: No parameters, returns a value

```c
#include <stdio.h>

int getFive(void)
{
    return 5;
}

int main(void)
{
    int x = getFive();
    printf("%d\n", x);
    return 0;
}
```

## Case 4: Parameters and return value

```c
#include <stdio.h>

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

int main(void)
{
    int result = multiply(4, 5);
    printf("%d\n", result);
    return 0;
}
```

This is the most common type.

## Understanding `void`

`void` means no value.

### As a return type

If a function does not return anything, use `void`.

```c
void showMessage(void)
{
    printf("Welcome\n");
}
```

### In the parameter list

If a function takes no parameters, write `void`.

```c
int getNumber(void)
{
    return 10;
}
```

In beginner C, this is better than leaving the parentheses empty.

## Parameters vs arguments

This is one of the most common confusion points.

### Parameters

These are variables written in the function definition.

```c
int add(int a, int b)
```

Here `a` and `b` are parameters.

### Arguments

These are the actual values passed when calling the function.

```c
add(3, 7);
```

Here `3` and `7` are arguments.

## Return values

A function can return a value to the caller.

Example:

```c
int square(int x)
{
    return x * x;
}
```

If you call:

```c
int result = square(5);
```

then `result` becomes `25`.

### Important rules

* the type of the returned value should match the function's return type
* once `return` executes, the function ends immediately
* a non-`void` function should return a value

## What happens after `return`?

Nothing in that function runs after `return`.

Example:

```c
int test(void)
{
    return 5;
    printf("This will never run\n");
}
```

The `printf` statement will never execute.

## Scope of variables

Scope means where a variable can be used.

## Local variables

Variables declared inside a function are local to that function.

```c
void example(void)
{
    int x = 10;
}
```

`x` only exists inside `example`.

## Example

```c
#include <stdio.h>

void show(void)
{
    int x = 5;
    printf("%d\n", x);
}

int main(void)
{
    show();
    // printf("%d\n", x);   invalid
    return 0;
}
```

`x` cannot be used in `main` because it belongs only to `show`.

## Lifetime of local variables

Local variables are created when the function starts and are destroyed when the function finishes.

So if you declare a variable inside a function, it does not keep its value between calls unless it is declared as `static`, which is a more advanced topic.

## Call by value in C

C uses call by value by default.

This means a copy of the argument is passed to the function, not the original variable itself.

Example:

```c
#include <stdio.h>

void change(int x)
{
    x = 100;
}

int main(void)
{
    int a = 10;
    change(a);
    printf("%d\n", a);
    return 0;
}
```

Output:

```c
10
```

Why? Because `change` received a copy of `a`, not the actual `a`.

## Modifying original variables using pointers

If you want a function to modify the original variable, you must pass its address using pointers.

Example:

```c
#include <stdio.h>

void change(int *x)
{
    *x = 100;
}

int main(void)
{
    int a = 10;
    change(&a);
    printf("%d\n", a);
    return 0;
}
```

Output:

```c
100
```

This is a more advanced use of functions and becomes very important later.

## Function flow step by step

Take this example:

```c
#include <stdio.h>

int subtract(int a, int b)
{
    return a - b;
}

int main(void)
{
    int result = subtract(10, 4);
    printf("%d\n", result);
    return 0;
}
```

### Execution flow

1. program starts at `main`
2. `main` calls `subtract(10, 4)`
3. `a = 10`, `b = 4`
4. function computes `10 - 4`
5. function returns `6`
6. `result` stores `6`
7. `printf` prints `6`

## Function prototypes in more detail

A function prototype must match the function definition.

Correct:

```c
int add(int a, int b);
```

Definition:

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

You can also write a prototype without parameter names:

```c
int add(int, int);
```

That is still valid.

## Good naming of functions

A function name should clearly describe what it does.

Good names:

* `calculateAverage`
* `printMenu`
* `isEven`
* `findLargest`

Poor names:

* `doStuff`
* `fun1`
* `abc`

Good naming makes code easier to read and understand.

## Designing a function

When creating a function, ask:

1. What task should this function perform?
2. What input does it need?
3. Should it return a result, or just do an action?
4. Can the task be kept small and focused?

Good functions usually do one clear thing.

## Example: checking even or odd

```c
#include <stdio.h>

int isEven(int n)
{
    if (n % 2 == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main(void)
{
    int num = 8;

    if (isEven(num))
    {
        printf("Even\n");
    }
    else
    {
        printf("Odd\n");
    }

    return 0;
}
```

This shows a function returning `1` for true and `0` for false.

## Example: function that prints instead of returns

```c
#include <stdio.h>

void checkEvenOdd(int n)
{
    if (n % 2 == 0)
    {
        printf("Even\n");
    }
    else
    {
        printf("Odd\n");
    }
}

int main(void)
{
    checkEvenOdd(8);
    return 0;
}
```

Both versions are valid, but they are used differently.

### Which is better?

Usually, returning a value is more flexible because the caller can decide what to do with it.

## Returning different data types

A function can return different types depending on its purpose.

## Returning an `int`

```c
int getAge(void)
{
    return 20;
}
```

## Returning a `float`

```c
float divide(float a, float b)
{
    return a / b;
}
```

## Returning a `char`

```c
char getGrade(void)
{
    return 'A';
}
```

## Returning nothing

```c
void printLine(void)
{
    printf("-----------\n");
}
```

## Multiple function examples in one program

```c
#include <stdio.h>

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

int subtract(int a, int b)
{
    return a - b;
}

void printResult(int value)
{
    printf("Result = %d\n", value);
}

int main(void)
{
    int x = add(5, 3);
    int y = subtract(10, 4);

    printResult(x);
    printResult(y);

    return 0;
}
```

This shows how functions can work together.

## Breaking a problem into functions

Suppose you want to write a program that:

* reads two numbers
* adds them
* prints the result

Instead of writing everything in `main`, split it up.

```c
#include <stdio.h>

int readNumber(void)
{
    int n;
    scanf("%d", &n);
    return n;
}

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

void printResult(int result)
{
    printf("Result = %d\n", result);
}

int main(void)
{
    int x, y, sum;

    printf("Enter first number: ");
    x = readNumber();

    printf("Enter second number: ");
    y = readNumber();

    sum = add(x, y);
    printResult(sum);

    return 0;
}
```

This is a strong example of modular programming.

## Why `main()` is also a function

`main()` is the entry point of a C program, and it is also a function.

Example:

```c
int main(void)
{
    return 0;
}
```

It has:

* a return type: `int`
* a name: `main`
* parameters: `void`
* a body

The program starts execution from `main`.

## Common mistakes with functions

## Mistake 1: forgetting the return statement

```c
int add(int a, int b)
{
    a + b;
}
```

This should be:

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

## Mistake 2: using `void` but trying to store the result

```c
void greet(void)
{
    printf("Hello\n");
}

int x = greet();   // invalid
```

A `void` function does not return a value.

## Mistake 3: wrong return type

```c
int getValue(void)
{
    return 3.5;
}
```

This may cause conversion issues. The return type and returned value should match.

## Mistake 4: forgetting function declaration

If the function is defined below `main`, declare it first.

## Mistake 5: passing wrong number of arguments

```c
int add(int a, int b);

add(5);   // invalid
```

The function expects two arguments, not one.

## Mistake 6: passing wrong type of arguments

```c
int square(int x);

square("hello");   // invalid
```

## Mistake 7: thinking changes inside a function affect the original variable automatically

Because C uses call by value, changing the parameter does not change the original unless pointers are used.

## Tracing functions manually

Students often struggle with function calls because they do not trace execution carefully.

Take this code:

```c
#include <stdio.h>

int doubleValue(int x)
{
    return x * 2;
}

int main(void)
{
    int a = 5;
    int b = doubleValue(a);
    printf("%d %d\n", a, b);
    return 0;
}
```

Trace it:

* `a = 5`
* `doubleValue(a)` means `doubleValue(5)`
* inside function, `x = 5`
* function returns `10`
* `b = 10`
* output is `5 10`

The original `a` stays unchanged.

## Nested function calls

A function call can be used inside another expression.

Example:

```c
#include <stdio.h>

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

int square(int x)
{
    return x * x;
}

int main(void)
{
    int result = square(add(2, 3));
    printf("%d\n", result);
    return 0;
}
```

### What happens?

* `add(2, 3)` returns `5`
* `square(5)` returns `25`
* `result` becomes `25`

## Functions and arrays

Functions can take arrays as parameters.

Example:

```c
#include <stdio.h>

void printArray(int arr[], int size)
{
    int i;
    for (i = 0; i < size; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main(void)
{
    int nums[] = {1, 2, 3, 4, 5};
    printArray(nums, 5);
    return 0;
}
```

This is important because arrays are commonly processed through functions.

## Functions that process arrays

```c
#include <stdio.h>

int findSum(int arr[], int size)
{
    int i, sum = 0;

    for (i = 0; i < size; i++)
    {
        sum += arr[i];
    }

    return sum;
}

int main(void)
{
    int nums[] = {2, 4, 6, 8};
    int total = findSum(nums, 4);
    printf("%d\n", total);
    return 0;
}
```

## Functions and strings

Strings are character arrays, so they are also often passed to functions.

Example:

```c
#include <stdio.h>

void printString(char str[])
{
    printf("%s\n", str);
}

int main(void)
{
    char name[] = "Alice";
    printString(name);
    return 0;
}
```

## Functions and structures

Functions can also take structures as parameters.

```c
#include <stdio.h>

struct Student
{
    int id;
    float grade;
};

void printStudent(struct Student s)
{
    printf("ID: %d\n", s.id);
    printf("Grade: %.2f\n", s.grade);
}

int main(void)
{
    struct Student st = {101, 88.5};
    printStudent(st);
    return 0;
}
```

This becomes useful when teaching structures later.

## Returning from a function early

You can use `return` to exit a function as soon as a condition is met.

Example:

```c
int isPositive(int n)
{
    if (n > 0)
    {
        return 1;
    }

    return 0;
}
```

This style is clean and common.

## Functions with multiple return paths

A function can have more than one `return`, as long as each possible path returns a value when needed.

Example:

```c
int max(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    else
    {
        return b;
    }
}
```

## Standard library functions

Not all functions are written by you. Many are already provided by libraries.

Examples:

* `printf()`
* `scanf()`
* `strlen()`
* `sqrt()`
* `pow()`

You use them by including the right header file.

Examples:

* `#include <stdio.h>`
* `#include <string.h>`
* `#include <math.h>`

So functions in C are of two broad types:

### Library functions

Already provided by C libraries.

### User defined functions

Written by the programmer.

## Recursion

Recursion is when a function calls itself.

This is an important topic, though sometimes taught after basic functions.

Example: factorial

```c
#include <stdio.h>

int factorial(int n)
{
    if (n == 0 || n == 1)
    {
        return 1;
    }

    return n * factorial(n - 1);
}

int main(void)
{
    printf("%d\n", factorial(5));
    return 0;
}
```

### How it works

* `factorial(5)` becomes `5 * factorial(4)`
* `factorial(4)` becomes `4 * factorial(3)`
* and so on until base case

### Important idea

Every recursive function must have a base case, otherwise it will call itself forever.

## Recursion vs loops

Many tasks can be solved using either loops or recursion.

For beginner students, loops are usually easier first. Recursion is useful for understanding function calls deeply, but can be harder to trace.

## Best practices for writing functions

### Keep functions small

One function should usually do one job.

### Use meaningful names

Function names should describe the task clearly.

### Avoid repeated code

If you are copying the same code in several places, consider making a function.

### Match return type correctly

Make sure the returned value matches the declared return type.

### Use comments only when necessary

A good function name often reduces the need for comments.

### Place prototypes neatly

Usually after `#include` lines and before `main`.

## How to teach functions effectively

If you are tutoring, do not start with syntax only. Start with the purpose.

A good teaching order is:

### Step 1

Show a program that repeats logic.

### Step 2

Ask, "Can we move this repeated logic into one reusable block?"

### Step 3

Introduce the function.

### Step 4

Explain input and output.

### Step 5

Practice calling the function several times with different values.

This makes the idea feel natural instead of random.

## Common student confusions

### "Why not just do everything in main?"

Because long programs become messy, repetitive, and hard to debug.

### "Why does the variable not change after I pass it to the function?"

Because C passes by value unless you use pointers.

### "Do I always need return?"

Only if the function's return type is not `void`.

### "What is the difference between printing and returning?"

Printing displays output immediately. Returning gives a value back to the caller so it can be used later.

This is a very important distinction.

## Printing vs returning

Compare these two:

### Version 1: prints directly

```c
void showSquare(int x)
{
    printf("%d\n", x * x);
}
```

### Version 2: returns value

```c
int square(int x)
{
    return x * x;
}
```

The second version is more flexible.

You can do:

```c
int result = square(5);
printf("%d\n", result);
```

or

```c
if (square(5) > 20)
{
    printf("Large\n");
}
```

Returning a value gives more control.

## Example set from easy to harder

## Example 1: add two numbers

```c
#include <stdio.h>

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

int main(void)
{
    printf("%d\n", add(3, 4));
    return 0;
}
```

## Example 2: find maximum of two numbers

```c
#include <stdio.h>

int max(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    return b;
}

int main(void)
{
    printf("%d\n", max(8, 5));
    return 0;
}
```

## Example 3: check if a number is positive

```c
#include <stdio.h>

int isPositive(int n)
{
    if (n > 0)
    {
        return 1;
    }
    return 0;
}

int main(void)
{
    if (isPositive(7))
    {
        printf("Positive\n");
    }
    else
    {
        printf("Not positive\n");
    }

    return 0;
}
```

## Example 4: sum of array elements

```c
#include <stdio.h>

int arraySum(int arr[], int size)
{
    int i, sum = 0;

    for (i = 0; i < size; i++)
    {
        sum += arr[i];
    }

    return sum;
}

int main(void)
{
    int nums[] = {1, 2, 3, 4};
    printf("%d\n", arraySum(nums, 4));
    return 0;
}
```

## Function call stack idea

At a beginner level, it is useful to know that when a function is called, the program temporarily jumps into that function, runs it, and then comes back.

For example:

```c
main -> add -> main
```

If one function calls another:

```c
main -> funcA -> funcB -> funcA -> main
```

This idea becomes very important for recursion and debugging.

## Practice questions

These are good exercises in order.

### Basic

1. write a function to add two integers
2. write a function to subtract two integers
3. write a function to return the square of a number
4. write a function to check whether a number is even

### Intermediate

5. write a function to return the larger of two numbers
6. write a function to return the largest of three numbers
7. write a function to count digits in an integer
8. write a function to find the sum of an array
9. write a function to check whether a number is prime

### More advanced

10. write a recursive factorial function
11. write a function that swaps two numbers using pointers
12. write a function that takes a structure and prints its fields

## Mini quiz section

Try asking your student these:

### Q1

What is the difference between a function declaration and a function definition?

### Q2

What is the difference between parameters and arguments?

### Q3

What does `void` mean in a function?

### Q4

Why does changing a parameter inside a function usually not change the original variable in `main`?

### Q5

What is the difference between printing a value and returning a value?

### Q6

Why are functions useful in large programs?

## Exam style theoretical points

These are the kind of lines students often need in written answers.

* A function is a named block of code designed to perform a specific task.
* Functions improve modularity, readability, reusability, and maintainability of programs.
* A function declaration tells the compiler the name, return type, and parameters of a function.
* A function definition contains the actual code of the function.
* In C, arguments are passed by value by default.
* A `void` function does not return a value.
* The `return` statement sends control and optionally a value back to the calling function.
* Local variables are only accessible within the function in which they are declared.

## Full worked example

This example combines several ideas together.

```c
#include <stdio.h>

int readNumber(void)
{
    int n;
    scanf("%d", &n);
    return n;
}

int max(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    return b;
}

void printResult(int value)
{
    printf("The larger number is %d\n", value);
}

int main(void)
{
    int x, y, bigger;

    printf("Enter first number: ");
    x = readNumber();

    printf("Enter second number: ");
    y = readNumber();

    bigger = max(x, y);
    printResult(bigger);

    return 0;
}
```

### What this demonstrates

* function declaration is not needed here because definitions come before `main`
* `readNumber` returns input value
* `max` returns the larger value
* `printResult` prints output
* `main` coordinates everything

This is a strong example of modular design.

## Final summary

Functions are one of the most important ideas in C programming.

They let you:

* break problems into smaller tasks
* avoid repeated code
* organize programs clearly
* make logic reusable
* build larger programs in a manageable way

To master functions, a student should be confident with:

* function syntax
* declarations, definitions, and calls
* parameters and arguments
* return values
* `void`
* local scope
* call by value
* the difference between printing and returning

Once these basics are clear, students are much more ready for:

* arrays with functions
* strings with functions
* structures with functions
* pointers and pass by reference
* dynamic memory allocation

## Best short definition to remember

A function in C is a reusable named block of code that performs a specific task, can take input through parameters, and can optionally return a value.


