C Programming — Full Overview
C Programming — Full Overview

C Programming — Full Overview

Created on:
Team Size: 1
Tool Used: Shell/C/GCC/GDB/Valgrind/Makefile

A structured progression through Shell commands, C programming fundamentals, and essential development tools. Each section links to its full dedicated post.

Shell

The terminal is your primary interface. Master these commands first:

CommandPurpose
ls -lalist all files with details
cd -toggle between last two directories
cp -rcopy directory recursively
mvmove or rename
chmod 755 / chmod +xset permissions
alias ll="ls -la"create a shortcut
source ~/.zshrcreload shell config
#!/bin/bashshebang — declare the Bash interpreter

Aliases added directly in the terminal are session-only. Persist them in ~/.zshrc.

Shell — Full Post

C Basics

Compile with -Wall -Wextra -Werror. No warnings tolerated.

gcc -Wall -Wextra -Werror main.c -o my_program

Key concepts:

  • Typeschar (1B), int (4B), float (4B), double (8B)
  • Pointersint *p = &x stores an address; *p dereferences it
  • Stringschar[] ending with '\0'; use pointer arithmetic to walk them
  • Memorymalloc allocates on the heap; every malloc needs a free
  • Bitwise& AND, | OR, ^ XOR, ~ NOT, << / >> shifts
  • (42 School Norm) Norminette — max 25 lines per function, no for/do…while, declarations at top
int *arr = malloc(5 * sizeof(int));
if (!arr)
    return (1);
free(arr);
arr = NULL;

Recursion

A recursive function calls itself with a smaller input until a base case stops it.

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

Each call pushes a stack frame. Too many calls without a base case → stack overflow (segfault). Recursion is natural for trees, linked lists, and divide-and-conquer problems.

Header Files

Headers (.h) declare the interface; sources (.c) define the implementation.

/* math_utils.h */
#ifndef MATH_UTILS_H
# define MATH_UTILS_H

int add(int a, int b);

#endif
  • Include guard#ifndef/#define/#endif prevents double inclusion
  • "file.h" for your own headers, <file.h> for system libraries
  • Never put function bodies in a header — only prototypes, typedefs, and #define

Makefile

Automates compilation. Run make instead of retyping gcc commands.

NAME   = my_program
CC     = gcc
CFLAGS = -Wall -Wextra -Werror
SRCS   = main.c utils.c
OBJS   = $(SRCS:.c=.o)

all: $(NAME)
$(NAME): $(OBJS)
	$(CC) $(CFLAGS) $(OBJS) -o $(NAME)
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@
clean:
	rm -f $(OBJS)
fclean: clean
	rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re

$< = the .c source, $@ = the .o target. Tabs required — not spaces.

Structs

Groups variables of different types under one name.

typedef struct s_point
{
    int x;
    int y;
}   t_point;

t_point  p = {10, 20};
t_point *ptr = &p;

p.x;      // access via variable
ptr->x;   // access via pointer

Self-referential structs are the foundation of linked lists and trees:

typedef struct s_node
{
    int           value;
    struct s_node *next;
}   t_node;

Linked Lists

A chain of heap-allocated nodes, each pointing to the next.

[val|next] → [val|next] → [val|next] → NULL
  • Push front O(1) — new node’s next = old head, update head
  • Push back O(n) — traverse to last node, set last->next = new node
  • Traverse — use a current pointer, never move head
  • Free — save next before free(current), set head = NULL after
void free_list(t_node **head)
{
    t_node *next;
    while (*head)
    {
        next = (*head)->next;
        free(*head);
        *head = next;
    }
}

Function Pointers

Stores the address of a function and calls it indirectly — enables callbacks and generic utilities.

int  (*op)(int, int);   // pointer to a function: (int, int) → int
op = &add;
op(3, 4);               // calls add

void * makes them generic — the caller casts inside the callback:

void apply(void *data, void (*f)(void *))
{
    f(data);
}

Used in ft_lstiter, ft_lstmap, and dispatch tables.

GDB

Compile with -g, then launch with gdbtui for the split source/command view:

gcc -g main.c -o my_program
gdbtui --args ./my_program arg1 arg2
CommandEffect
b <line>breakpoint
rrun
nnext (step over)
sstep (step into)
ccontinue
print <expr>inspect once
disp <expr>inspect on every step
btcall stack (essential after a crash)
refredraw TUI

Valgrind

Detects memory errors at runtime. Always compile with -g first:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes -s ./my_program
OutputMeaning
definitely lostmalloc with no surviving pointer — must fix
still reachablepointer exists but never freed — fix before exit
Invalid read/writeout-of-bounds access
Uninitialised valuevariable used before assignment
Invalid freedouble free or freeing a non-heap pointer

A clean run shows ERROR SUMMARY: 0 errors from 0 contexts.

© 2026 Samuel Styles