Docs

Functions

Functions in C

šŸ“– Introduction

A function is a self-contained block of code that performs a specific task. Functions allow you to break complex programs into smaller, manageable pieces. This promotes code reusability, readability, and easier debugging.


šŸŽÆ Why Use Functions?

Without Functions:                 With Functions:
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”       ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ main() {                │       │ main() {                │
│   // 100 lines for      │       │   readInput();          │
│   // reading input      │       │   processData();        │
│                         │       │   displayResults();     │
│   // 200 lines for      │       │ }                       │
│   // processing         │       │                         │
│                         │       │ void readInput() {...}  │
│   // 100 lines for      │       │ void processData() {...}│
│   // output             │       │ void displayResults()...│
│ }                       │       ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
     Hard to maintain              Organized & Reusable

Benefits:

BenefitDescription
ModularityBreak code into logical pieces
ReusabilityWrite once, use many times
ReadabilityEasier to understand
DebuggingIsolate and fix bugs easily
CollaborationDifferent programmers work on different functions

šŸ“ Function Syntax

Structure:

return_type function_name(parameter_list) {
    // Function body
    // Statements
    return value;  // Optional, based on return_type
}

Components:

    ā”Œā”€ā”€ā”€ Return Type (what the function gives back)
    │
    │          ā”Œā”€ā”€ā”€ Function Name (identifier)
    │          │
    │          │               ā”Œā”€ā”€ā”€ Parameters (inputs)
    │          │               │
    ā–¼          ā–¼               ā–¼
   int       add         (int a, int b)
   {
       return a + b;   ◄─── Return Statement
   }
       ā–²
       │
       └─── Function Body (what it does)

šŸ”§ Function Types

1. No Return, No Parameters:

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

// Call:
greet();

2. No Return, With Parameters:

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

// Call:
printSum(5, 3);  // Output: Sum: 8

3. With Return, No Parameters:

int getRandomNumber(void) {
    return 42;
}

// Call:
int num = getRandomNumber();

4. With Return, With Parameters:

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

// Call:
int result = add(10, 20);  // result = 30

šŸ“Š Function Declaration vs Definition

Declaration (Prototype):

Tells the compiler about the function's signature.

// Declaration (prototype) - usually at top of file or in header
int add(int a, int b);       // With parameter names (optional)
int multiply(int, int);      // Without parameter names (valid)

Definition:

The actual implementation of the function.

// Definition - the full function
int add(int a, int b) {
    return a + b;
}

Complete Example:

#include <stdio.h>

// Declaration (prototype)
int square(int n);
void printLine(void);

int main() {
    printLine();
    printf("Square of 5: %d\n", square(5));
    printLine();
    return 0;
}

// Definitions
int square(int n) {
    return n * n;
}

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

šŸ”„ Function Call Flow

main()                          square(5)
  │                               │
  │ Call square(5)                │
  ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā–ŗ  │
  │                               │ n = 5
  │                               │ Calculate 5 * 5
  │                               │ return 25
  │ Receive 25                    │
  │◄────────────────────────────  │
  │                               │
  ā–¼ Continue execution            ā–¼

šŸ“„ Parameters and Arguments

Terminology:

  • •Parameters: Variables in function definition (formal parameters)
  • •Arguments: Values passed during function call (actual parameters)
//           Parameters
//           ↓       ↓
int add(int a, int b) {
    return a + b;
}

int main() {
    int x = 5, y = 10;
    int sum = add(x, y);  // x and y are Arguments
    //        ↑    ↑
    //       Arguments
}

Pass by Value:

C passes arguments by value - a copy is made.

void increment(int n) {
    n = n + 1;  // Changes local copy only!
    printf("Inside: %d\n", n);
}

int main() {
    int x = 5;
    increment(x);
    printf("Outside: %d\n", x);  // Still 5!
    return 0;
}
// Output:
// Inside: 6
// Outside: 5

šŸ“¤ Return Values

Single Return:

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

Multiple Return Points:

int grade(int score) {
    if (score >= 90) return 'A';
    if (score >= 80) return 'B';
    if (score >= 70) return 'C';
    if (score >= 60) return 'D';
    return 'F';
}

Return with Expression:

int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

void Return:

void printError(int code) {
    if (code == 0) {
        return;  // Early exit, no value
    }
    printf("Error code: %d\n", code);
}

šŸ”¢ Data Types for Return

Return TypeDescriptionExample
voidNo return valuevoid printHello()
intIntegerint getAge()
floatFloating pointfloat getAverage()
doubleDouble precisiondouble calculatePi()
charSingle characterchar getGrade()
int*Pointerint* createArray()

šŸ“š Standard Library Functions

C provides many built-in functions:

stdio.h:

printf("Hello");      // Print formatted output
scanf("%d", &n);      // Read input
puts("String");       // Print string with newline
getchar();            // Read single character

string.h:

strlen(str);          // String length
strcpy(dest, src);    // Copy string
strcmp(s1, s2);       // Compare strings
strcat(dest, src);    // Concatenate strings

math.h:

sqrt(x);              // Square root
pow(x, y);            // x to the power y
abs(x);               // Absolute value
sin(x), cos(x);       // Trigonometric functions

stdlib.h:

malloc(size);         // Allocate memory
free(ptr);            // Free memory
rand();               // Random number
atoi(str);            // String to integer

šŸ”„ Function Scope

Local Variables:

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

void function2() {
    // x is NOT accessible here!
    int y = 20;  // Local to function2
}

Global Variables:

int globalVar = 100;  // Accessible everywhere

void function1() {
    printf("%d\n", globalVar);  // Works!
}

void function2() {
    globalVar = 200;  // Modified!
}

Variable Scope Diagram:

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Global Scope                                 │
│  int globalVar;                              │
│                                              │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  │
│  │ function1()                            │  │
│  │  int localA;  // Only here             │  │
│  │  // globalVar accessible               │  │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  │
│                                              │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  │
│  │ function2()                            │  │
│  │  int localB;  // Only here             │  │
│  │  // localA NOT accessible!             │  │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  │
│                                              │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

šŸŽØ Best Practices

1. Naming Conventions:

// Good - descriptive names
int calculateArea(int length, int width);
void printStudentInfo(char* name, int age);

// Bad - vague names
int calc(int l, int w);
void print(char* n, int a);

2. Single Responsibility:

// Good - one task per function
int calculateSum(int arr[], int size);
void printArray(int arr[], int size);

// Bad - doing too much
void calculateAndPrintSum(int arr[], int size);

3. Function Length:

  • •Keep functions short (< 50 lines ideally)
  • •If too long, break into smaller functions

4. Documentation:

/**
 * Calculates the factorial of a number.
 *
 * @param n The number to calculate factorial for
 * @return The factorial of n, or -1 if n is negative
 */
int factorial(int n) {
    if (n < 0) return -1;
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

āš ļø Common Mistakes

1. Forgetting Return:

// Wrong - should return something
int add(int a, int b) {
    int sum = a + b;
    // Forgot return!
}

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

2. Wrong Return Type:

// Wrong - returning float but declared int
int divide(int a, int b) {
    return (float)a / b;  // Truncated!
}

// Correct
float divide(int a, int b) {
    return (float)a / b;
}

3. Missing Prototype:

int main() {
    greet();  // Error: function not declared!
    return 0;
}

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

šŸ”‘ Key Takeaways

  1. •Functions divide code into reusable blocks
  2. •Declare (prototype) before use, define anywhere
  3. •C uses pass by value - copies are passed
  4. •Use return to send back a value
  5. •void means no return value
  6. •Keep functions focused on one task
  7. •Use descriptive function names

ā­ļø Next Topic

Continue to Function Parameters to learn about different parameter passing techniques.

Functions - C Programming Tutorial | DeepML