Functions In C Lang

Master function declaration, definition, call by value semantics, stack frames, calling conventions, and recursion to write efficient, modular C code.

What is a Function?

A reusable block of code that performs a specific task. Functions organize code into logical units.

Key Concept: Every function has a name, parameters (inputs), a return type, and a body. The simplest function is main(), where execution begins.

Declaration vs Definition

The blueprint versus the implementation.

Declaration (Prototype)

Tells the compiler about a function before it's used. Includes name, return type, and parameters.

// Before main() int add(int a, int b); void printMsg(char *msg);

Definition (Body)

The actual implementation containing the code to execute.

// Implementation int add(int a, int b) { return a + b; }
functions.c
#include <stdio.h> // 1. Declaration int multiply(int x, int y); int main() { int result = multiply(5, 3); printf("Result: %d\n", result); return 0; } // 2. Definition int multiply(int x, int y) { return x * y; }

Call by Value

C passes copies of arguments, not originals. Changes inside functions don't affect the caller.

value.c
void increment(int x) { x = x + 1; // Modifies COPY of x } int main() { int num = 10; increment(num); // num is STILL 10 here! }
main() Memory: increment() Memory: ┌─────────────┐ ┌─────────────┐ │ num = 10 │ ──COPY─>│ x = 10 │ └─────────────┘ └─────────────┘ ↓ ┌─────────────┐ │ x = 11 │ (Modified only here) └─────────────┘

Return Values

Exiting a function and sending data back to the caller.

Return Value

Returns a result to the caller.

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

Return Void

Returns nothing.

void sayHello() { printf("Hi"); return; // Optional }

Stack Architecture

How memory manages function calls. Every call creates a "Stack Frame".

Step 1: main() called ┌─────────────────────┐ │ [STACK FRAME: main] │ │ main_var = 5 │ └─────────────────────┘ Step 2: func1(5) called ┌─────────────────────┐ │ [STACK FRAME: func1]│ │ x = 5 │ ├─────────────────────┤ │ [STACK FRAME: main] │ └─────────────────────┘ Step 3: func2(15) called ┌─────────────────────┐ │ [STACK FRAME: func2]│ <--- Top of Stack │ y = 15 │ ├─────────────────────┤ │ [STACK FRAME: func1]│ ├─────────────────────┤ │ [STACK FRAME: main] │ └─────────────────────┘
Memory Rules:
• LIFO (Last In, First Out) structure.
• Local variables exist only in their frame.
• Returning destroys the frame.
• Deep recursion can cause Stack Overflow.

Calling Conventions (x86-64)

How the CPU passes data between functions at the machine level.

Parameters (Input)

First 6 integer args go into registers:

  • 1: RDI
  • 2: RSI
  • 3: RDX
  • 4: RCX
  • 5: R8
  • 6: R9

Return (Output)

Where the result goes:

  • Integer: RAX Register
  • Float: XMM0 Register
assembly_concept.c
// C Code: int result = add(10, 20); // Assembly (Concept): MOV RDI, 10 // Arg 1 MOV RSI, 20 // Arg 2 CALL add MOV result, RAX // Return value

Recursion

A function calling itself. Requires a Base Case to stop.

factorial.c
int factorial(int n) { // Base Case if (n <= 1) return 1; // Recursive Case return n * factorial(n - 1); } // Execution: 5 * 4 * 3 * 2 * 1 = 120