Skip to main content

Overview

The 0x02-functions_nested_loops module teaches you to write modular, reusable code. You’ll create custom functions, work with header files, implement nested loops, and build practical programs like times tables and character validators.

Header Files

main.h - Function Prototypes

Header files declare function prototypes, allowing functions to be used across multiple files.
main.h
int _putchar(char c);
void print_alphabet(void);
void print_alphabet_x10(void);
int _islower(int c);
int _isalpha(int c);
int print_sign(int n);
int _abs(int);
int print_last_digit(int);
void jack_bauer(void);
void times_table(void);
int add(int, int);
void print_to_98(int n);
Function prototypes end with a semicolon and don’t include the implementation. They tell the compiler what functions exist and their signatures.
Include main.h in every .c file that uses these functions: #include "main.h"

Creating Functions

Void Functions (No Return Value)

1-alphabet.c
#include "main.h"
/**
   * print_alphabet - Entry point
   *Description: This program prints the alphabet in lowercase
   *followed by a new line.
   *Return: nothing
*/


void print_alphabet(void)
{
char alphabet;

for (alphabet = 'a'; alphabet <= 'z'; alphabet++)
_putchar(alphabet);
_putchar('\n');
}
Function components:
  • Return type: void (returns nothing)
  • Function name: print_alphabet
  • Parameters: (void) (takes no arguments)
  • Body: Implementation in curly braces

Using Custom Functions

0-putchar.c
#include <unistd.h>
#include "main.h"
/**
   * main - Entry point
   *Description: This program prints prints _putchar,
   *followed by a new line
   *Return: 0 on success
*/

int main(void)
{
char word[8] = "_putchar";
int i;

for (i = 0; i < 8; i++)
_putchar(word[i]);
_putchar('\n');
return (0);
}
The _putchar() function is a custom implementation of putchar. The underscore prefix distinguishes it from the standard library version.

Functions with Return Values

Character Validation - _islower()

3-islower.c
#include "main.h"
/**
   * _islower - Entry point
   * @c: The character to check
   *Description: checks for lowercase character
   *Return: 1 if c is lowercase and 0 otherwise
*/

int _islower(int c)
{
return (c >= 97 && c <= 122);
}
  • Lowercase ‘a’ to ‘z’: 97 to 122
  • Uppercase ‘A’ to ‘Z’: 65 to 90
  • Digits ‘0’ to ‘9’: 48 to 57
Return value:
  • Returns 1 (true) if lowercase
  • Returns 0 (false) otherwise

Alphabet Validation - _isalpha()

4-isalpha.c
#include "main.h"
/**
   * _isalpha - Entry point
   * @c: The character to check
   *Description: if c is alphabet or not
   *Return: 1 if c is uppercase or lowercase and 0 otherwise
*/

int _isalpha(int c)
{
return ((c >= 65 && c <= 90) || (c >= 97 && c <= 122));
}
The || operator means “OR”. The function returns true if the character is either uppercase (65-90) or lowercase (97-122).

Simple Math - add()

10-add.c
#include "main.h"
/**
 * add - function that adds two integers
 * @n: first integer
 * @k: second integer
 * Description: function that adds two integers
 * Return: sum of n and k
 */

int add(int n, int k)
{
return (n + k);
}

Function Documentation

Proper documentation follows the Betty style:
/**
 * function_name - Brief description
 * @param1: Description of first parameter
 * @param2: Description of second parameter
 * 
 * Description: Detailed description (optional)
 * Return: Description of return value
 */
Always document:
  1. What the function does
  2. Each parameter’s purpose
  3. What the function returns

Nested Loops

Times Table Implementation

Nested loops allow you to work with multidimensional patterns:
9-times_table.c
#include "main.h"

/**
 * times_table - function that prints the 9 times table, starting with 0
 * Description: function that prints the 9 times table, starting with 0
 * Return: void
 */
void times_table(void)
{
int i, j, k;

for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
{
k = i * j;
if ((k / 10) == 0)
{
if (j != 0)
_putchar(' ');
_putchar(k + '0');
if (j == 9)
continue;
_putchar(',');
_putchar(' ');
}
else
{
_putchar((k / 10) + '0');
_putchar((k % 10) + '0');
if (j == 9)
continue;
_putchar(',');
_putchar(' ');
}
}
_putchar('\n');
}
}
Breaking down the logic:
for (i = 0; i <= 9; i++)
Controls the rows (0 through 9)

Digit Extraction

The times table uses clever math to print individual digits:
k = 42;
_putchar((k / 10) + '0');  /* Prints '4' - tens digit */
_putchar((k % 10) + '0');  /* Prints '2' - ones digit */
  • k / 10 extracts tens digit (42 / 10 = 4)
  • k % 10 extracts ones digit (42 % 10 = 2)
  • Adding '0' converts number to character

Function Types Comparison

void print_message(void)
{
    _putchar('H');
    _putchar('i');
    /* No return statement needed */
}

Scope and Variables

Local Variables

Variables declared inside a function only exist within that function:
int _islower(int c)
{
    /* c is local to this function */
    return (c >= 97 && c <= 122);
}

Function Parameters

C passes arguments by value, meaning the function gets a copy:
int add(int n, int k)
{
    n = n + k;  /* Modifying n here doesn't affect caller */
    return (n);
}
The original variables in the caller remain unchanged.

Compilation with Multiple Files

When working with multiple files:
# Compile all .c files together
gcc -Wall -Werror -Wextra -pedantic -std=gnu89 main.c 1-alphabet.c _putchar.c -o alphabet

# Run the program
./alphabet
You need to compile all .c files but only include the .h file (don’t compile header files).

Best Practices

One function, one purposeEach function should do one thing well. _islower() only checks if a character is lowercase - nothing more.
Use descriptive names
  • print_alphabet() clearly describes what it does
  • add() is simple and obvious
  • Avoid names like func1() or do_stuff()
Keep functions shortIf a function is too long, consider breaking it into smaller helper functions.

Common Patterns

Character Output Loop

void print_string(char *str)
{
    int i;
    
    for (i = 0; str[i] != '\0'; i++)
        _putchar(str[i]);
}

Range Validation

int is_in_range(int value, int min, int max)
{
    return (value >= min && value <= max);
}

Absolute Value

int _abs(int n)
{
    if (n < 0)
        return (-n);
    return (n);
}

Nested Loops - More Examples

Rectangle Pattern

void print_rectangle(int width, int height)
{
    int i, j;
    
    for (i = 0; i < height; i++)  /* Rows */
    {
        for (j = 0; j < width; j++)  /* Columns */
            _putchar('#');
        _putchar('\n');
    }
}

Triangle Pattern

void print_triangle(int size)
{
    int i, j;
    
    for (i = 1; i <= size; i++)  /* Row number */
    {
        for (j = 0; j < i; j++)  /* Print i characters */
            _putchar('#');
        _putchar('\n');
    }
}

Testing Your Functions

Create test files to verify function behavior:
main.c (example)
#include "main.h"

int main(void)
{
    print_alphabet();
    print_alphabet_x10();
    
    _putchar('0' + _islower('a'));
    _putchar('0' + _islower('A'));
    _putchar('\n');
    
    times_table();
    
    return (0);
}
Test edge cases: empty inputs, zero values, maximum values, and boundary conditions.

Common Errors

error: implicit declaration of function 'print_alphabet'
Fix: Include main.h with the function prototype.
void get_number(void)
{
    return (42);  /* Error: void function can't return value */
}
Fix: Change return type to int.
int add(int a, int b)
{
    int sum = a + b;
    /* Missing return! */
}
Fix: Add return (sum);

Build docs developers (and LLMs) love