Modularization
in C
Subprograms, Functions, Procedures and the art of dividing to conquer.
↓ scroll to continue
What is Modularization?
Breaking a large problem into small, manageable parts
✗ The Monolith
✓ Modularized
ANALOGY
You don't sculpt from a whole rock — you build with LEGO. Each piece has a defined shape, fits with others, and can be reused in any construction.
Subprograms
In C, every subprogram is a function. There is nothing else.
Anatomy of a Function
int resultado = a + b;
return resultado;
}
REUSABILITY
Once defined, the function can be called infinitely many times from any part of the program.
ABSTRACTION
You don't need to know how it works to use it. Only what it receives and what it returns.
int y = sumar(100, 200); // y = 300
int z = sumar(x, y); // z = 310
Functions vs Procedures
The difference is whether they return something or not
PROCEDURE
void — executes an action, returns nothing
Like a worker who does the task and thats it
printf("1. Ingresar\n");
printf("2. Salir\n");
// no hay return
}
FUNCTION
with return type — calculates and returns a value
Like a worker who brings back the result
return a + b;
}
int r = sumar(3, 4); // r = 7
Local Variables
They live inside the function. When it ends, they disappear.
EXECUTION STACK
Each call stacks a new "drawer" with its local vars
int area = base * altura;
return area;
}
int main() {
int r = calcular(10, 5);
// 'area' DOES NOT exist here
// printf("%d", area); → ERROR
}
⚠ Compilation Error
Trying to use area outside of calcular() fails. The local variable does not exist outside its scope. The compiler tells you right to your face.
Global Variables
Declared outside any function. Everyone can see them... and modify them.
GLOBAL VARIABLE
void incrementar() {
contador++;
}
void resetear() {
contador = 0;
}
int main() {
incrementar();
incrementar();
resetear(); // surprise!
}
⚠ DANGER: Ghost Effect
resetear() modifies contador without anyone expecting it. This kind of bug is a nightmare to debug.
Use globals only when strictly necessary.
Local vs Global
And the mystery of shadowing: when a variable hides another
void miFuncion() {
int x = 5; // LOCAL x — HIDES the global
printf("%d", x); // prints 5, not 100
} // the local x disappears here
int main() {
printf("%d", x); // prints 100 (the global)
miFuncion(); // prints 5
printf("%d", x); // still 100
}
LOCAL (cyan)
Exists only inside its block. It has priority over the global of the same name within that scope. When the block ends, it disappears from the stack.
GLOBAL (amber)
Visible from any function. If a function has a local with the same name, the global becomes hidden (shadowed) inside that function.
Pass by Value
The value is copied. The original remains intact.
x is 5 in the main frame n inc(), n becomes 6 (n++) n disappears. x still equals 5. The original was not touched. n++; // modifies the copy, not the original
}
int main() {
int x = 5;
inc(x); // passes a COPY of x
printf("%d", x); // prints 5 — unchanged
}
Pass by Reference
The memory address is passed. The original IS modified.
x is 5 at address 0xFF01 &x (the address) is passed. The pointer p receives 0xFF01 *p = 10 follows the address and modifies the memory at 0xFF01 p disappears, but the damage is done. x now equals 10. The original was modified. *p = 10; // dereference: modifies what it points to
}
int main() {
int x = 5;
cambiar(&x); // passes the ADDRESS of x
printf("%d", x); // prints 10 — was modified
}
Value vs Reference
Same starting point, completely different result
BY VALUE
BY REFERENCE
| Aspect | By Value | By Reference (pointer) |
|---|---|---|
| What is passed | Copy of the value | Memory address |
| Modifies original | NO ✔ | YES ⚠ |
| Syntax at call | func(x) | func(&x) |
| Syntax at parameter | int n | int *p |
| When to use | Read data, calculate | Modify the original |
Formal and Actual Parameters
Definition vs call. Placeholder vs real value.
FORMAL PARAMETERS
Those in the DEFINITION — are placeholders, local variables
return base * altura;
}
They are like normal variables inside the function. They get assigned a value at the call.
ACTUAL PARAMETERS
Those in the CALL — the real values being passed
These are the concrete values (literals, variables or expressions) sent in the call.
POSITIONAL CORRESPONDENCE — order matters
// base=10, altura=20 → result = 200
// Order DOES matter in many cases:
dividir(10, 2); // 10 / 2 = 5
dividir(2, 10); // 2 / 10 = 0 (VERY different result)
Complete Example
A program that uses EVERYTHING we saw
// GLOBAL: visible in all functions
int llamadas = 0;
// FUNCTION: returns the area (by value)
int areaRectangulo(int base, int altura) {
llamadas++; // modifies global
int area = base * altura; // LOCAL
return area;
}
// PROCEDURE: prints (void, no return)
void imprimirResultado(int valor) {
printf("Resultado: %d\n", valor);
}
// BY REFERENCE: duplicates the original
void duplicar(int *p) {
*p *= 2;
}
int main() {
// formals: base, altura — actuals: 5, 10
int area = areaRectangulo(5, 10);
imprimirResultado(area); // 50
duplicar(&area); // passes address — by reference
imprimirResultado(area); // 100
printf("Llamadas: %d\n", llamadas); // 1
return 0;
}
GLOBAL
llamadas — visible in all functions
LOCAL
area inside areaRectangulo — only there
POINTER
*p in duplicar — modifies the original
Golden Rules
Burn them into memory. Forever.
Modularize: short functions that do ONE thing
If your function needs a comment explaining what it does, its too long.
Prefer local variables over globals
Globals create hidden dependencies and impossible-to-track bugs.
Pass by value: safe, the original does not change
Use it when you only need to read or calculate something from the data.
Pass by reference (*pointers): when you NEED to modify the original
Be explicit. Whoever reads the code needs to know the function has side effects.
Formal parameters = definition, actuals = call
The order of actuals must match the order of formals. Always.
Each function = one responsibility
Single Responsibility Principle. It applies in C, in any language, in any paradigm.
SESSION ENDED
Now you know how to modularize in C. Now think in modules.
PROGRAMIERDS — 2026