|$ curl https://forge-ai.dev/api/markdown?path=docs/c
$cat docs/c-programming-—-getting-started.md
updated Recently·45 min read·published

C Programming — Getting Started

CProgrammingSystemsBeginnerBeginner🎯Free Tools
What is C?

C is a general-purpose, procedural programming language developed between 1969 and 1973 by Dennis Ritchie at Bell Labs. Originally designed for rewriting the UNIX operating system, C has become one of the most influential and widely used programming languages in history. It provides low-level access to memory, simple machine-level constructs, and a clean syntax that maps efficiently to machine instructions.

C is the foundation of modern computing. Operating systems (Linux, Windows, macOS kernels), databases (PostgreSQL, MySQL), compilers (GCC, Clang), interpreters (CPython, Ruby MRI), embedded systems, game engines, and countless other critical systems are written in C. Learning C gives you a deep understanding of how computers actually work — memory, pointers, data structures, and the relationship between software and hardware.

Unlike higher-level languages, C does not have garbage collection, classes, or runtime safety nets. You manage memory directly, you choose data structures explicitly, and you deal with the consequences of your choices. This is what makes C both powerful and demanding — it gives you full control with zero hand-holding.

Why Learn C?
Foundation: Understand how computers work at the lowest level
Performance: Write code that runs as fast as the hardware allows
Portability: C runs on virtually every platform ever made
Embedded: Microcontrollers, IoT devices, firmware — all C
Systems: OS kernels, drivers, compilers, databases
Career: Essential for systems, security, and embedded roles
History of C

C evolved from earlier languages in a clear lineage. Understanding this history explains why C has the features it does and why certain design decisions were made.

YearMilestoneSignificance
1972C created by Dennis RitchieDeveloped at Bell Labs for rewriting UNIX
1978The C Programming Language (K&R)First formal description, "K&R C"
1989ANSI C (C89/C90)First standardized version
1999C99Added inline functions, long long, variable-length arrays
2011C11Added threads, atomics, generic selections, static_assert
2018C17/C18Minor bug fixes to C11, no major new features
2023C23Added nullptr, typeof, constexpr, improved Unicode support
📝

note

This guide covers C17 (the current stable standard) with notes on C23 additions where relevant. Most code examples work with any C99+ compiler. The C language standard is maintained by ISO/IEC JTC1/SC22/WG14.
Environment Setup

To write and compile C programs, you need a compiler. The most common compilers are GCC (GNU Compiler Collection) and Clang. Both are free, open-source, and available on every major platform.

macOS

terminal
Bash
1# Install Xcode Command Line Tools (includes clang)
2xcode-select --install
3
4# Or install GCC via Homebrew
5brew install gcc
6
7# Verify installation
8gcc --version
9clang --version

Linux (Ubuntu/Debian)

terminal
Bash
1# Install GCC
2sudo apt update
3sudo apt install build-essential
4
5# Verify
6gcc --version
7
8# Install GDB debugger
9sudo apt install gdb

Windows

terminal
Bash
1# Option 1: Install MinGW-w64 (native Windows GCC)
2# Download from https://www.mingw-w64.org/
3
4# Option 2: Install WSL2 and use Linux toolchain
5wsl --install
6# Then follow Linux instructions inside WSL
7
8# Option 3: Use MSYS2
9# Download from https://www.msys2.org/
10pacman -S mingw-w64-x86_64-gcc

Editor Setup

Any text editor works for C development. For a good experience, use VS Code with the C/C++ extension (IntelliSense, debugging), or Vim/Neovim with clangd for a terminal-based workflow.

Your First C Program

Every C program starts executing from the main() function. This is the entry point — the operating system calls main()when your program starts. Let's write, compile, and run the classic "Hello, World!" program.

hello.c
C
1#include <stdio.h>
2
3int main(void) {
4 printf("Hello, World!\n");
5 return 0;
6}

Line-by-Line Breakdown

#include <stdio.h> — Preprocessor directive. Copies the contents of the standard I/O header file into your source file. Provides printf(), scanf(), and other I/O functions.
int main(void) — The main function. Returns an int (exit status). The void parameter means it takes no arguments.
printf(...) — Prints formatted output to stdout. \\n is the newline escape sequence.
return 0; — Returns 0 to the operating system. Convention: 0 means success, non-zero means error.

Compile and Run

terminal
Bash
1# Compile: source file → executable
2gcc hello.c -o hello
3
4# Run the executable
5./hello
6# Output: Hello, World!
7
8# Compile with warnings enabled (always do this)
9gcc -Wall -Wextra -pedantic -std=c17 hello.c -o hello
10
11# Compile with debugging symbols
12gcc -g -Wall -Wextra hello.c -o hello

warning

Always compile with -Wall -Wextra. These flags enable most compiler warnings that catch real bugs. Treat warnings as errors in your code — they exist to help you write correct programs.
How Compilation Works

C is a compiled language — your source code is translated into machine code by a compiler before execution. This is different from interpreted languages like Python or JavaScript. Understanding the compilation process helps you write better code and debug more effectively.

Compilation Pipeline
hello.c → Preprocessor (#include, #define) hello.i (expanded source) hello.i → Compiler (parse, optimize) hello.s (assembly code) hello.s → Assembler hello.o (object file, machine code) hello.o → Linker (connect libraries) hello (executable binary)
terminal
Bash
1# See each stage independently
2gcc -E hello.c -o hello.i # Preprocess only
3gcc -S hello.c -o hello.s # Compile to assembly
4gcc -c hello.c -o hello.o # Compile to object file
5gcc hello.o -o hello # Link into executable
6
7# Or all in one step
8gcc hello.c -o hello
Basic Syntax

C syntax is clean and minimal. Programs are made up of functions, statements, and declarations. Semicolons terminate statements, curly braces define blocks, and every variable must be declared before use.

syntax.c
C
1#include <stdio.h>
2
3// Function declaration (prototype)
4int add(int a, int b);
5
6int main(void) {
7 // Variable declaration and initialization
8 int x = 10;
9 int y = 20;
10 int sum;
11
12 // Function call
13 sum = add(x, y);
14
15 // printf with format specifiers
16 printf("%d + %d = %d\n", x, y, sum);
17
18 // Comments: single-line
19 /* Multi-line
20 comment */
21
22 return 0;
23}
24
25// Function definition
26int add(int a, int b) {
27 return a + b;
28}

Key Syntax Rules

Every statement ends with a semicolon ;
Code blocks are delimited by curly braces { }
Variable declarations must appear before statements in a block (C89). C99+ allows declarations anywhere.
Function prototypes should be declared before main() or in header files.
C is case-sensitive: main and Main are different identifiers.
Whitespace (spaces, tabs, newlines) is mostly insignificant — used for readability.
Variables Overview

Variables in C are named storage locations with a specific type. Unlike dynamically-typed languages, C requires you to declare the type of every variable at compile time. The compiler uses this information to allocate the right amount of memory and perform type checking.

variables-overview.c
C
1#include <stdio.h>
2
3int main(void) {
4 // Integer types
5 int age = 25;
6 long population = 7900000000LL;
7 unsigned int count = 42;
8
9 // Floating-point types
10 float pi = 3.14f;
11 double precise = 3.141592653589793;
12
13 // Character type
14 char grade = 'A';
15
16 // Print sizes (in bytes)
17 printf("int: %zu bytes\n", sizeof(int));
18 printf("long: %zu bytes\n", sizeof(long));
19 printf("float: %zu bytes\n", sizeof(float));
20 printf("double: %zu bytes\n", sizeof(double));
21 printf("char: %zu byte\n", sizeof(char));
22
23 return 0;
24}

info

Use sizeof to determine the size of any type in bytes. The size of int is typically 4 bytes, double is 8 bytes, and char is always 1 byte. Sizes can vary between platforms — always use sizeof instead of hardcoding sizes.
Format Specifiers

printf() and scanf() use format specifiers to read and write different data types. Using the wrong format specifier is undefined behavior — a common source of bugs.

SpecifierTypeExample
%dintprintf("%d", 42)
%ldlongprintf("%ld", 100000L)
%uunsigned intprintf("%u", 42u)
%fdouble (printf) / float (scanf)printf("%f", 3.14)
%lfdouble (scanf)scanf("%lf", &val)
%ccharprintf("%c", 'A')
%schar array (string)printf("%s", "hi")
%ppointer (void*)printf("%p", ptr)
%zusize_tprintf("%zu", sizeof(int))
%xhexadecimalprintf("%x", 255)
%ooctalprintf("%o", 255)
Control Flow Overview

C provides standard control flow constructs: if/else for branching, for/while/do-while for loops, and switch for multi-way branching.

control-flow.c
C
1#include <stdio.h>
2
3int main(void) {
4 int score = 85;
5
6 // if / else if / else
7 if (score >= 90) {
8 printf("Grade: A\n");
9 } else if (score >= 80) {
10 printf("Grade: B\n");
11 } else {
12 printf("Grade: C\n");
13 }
14
15 // for loop
16 for (int i = 0; i < 5; i++) {
17 printf("Count: %d\n", i);
18 }
19
20 // while loop
21 int n = 3;
22 while (n > 0) {
23 printf("Down: %d\n", n);
24 n--;
25 }
26
27 // switch
28 char op = '+';
29 int a = 10, b = 5;
30 switch (op) {
31 case '+': printf("Result: %d\n", a + b); break;
32 case '-': printf("Result: %d\n", a - b); break;
33 case '*': printf("Result: %d\n", a * b); break;
34 default: printf("Unknown op\n"); break;
35 }
36
37 return 0;
38}
Functions Overview

Functions are the building blocks of C programs. A function is a reusable block of code that performs a specific task. C functions can accept parameters, return values, and call themselves (recursion).

functions-overview.c
C
1#include <stdio.h>
2#include <math.h>
3
4// Function: returns the nth Fibonacci number
5// Uses recursion — a function calling itself
6int fibonacci(int n) {
7 if (n <= 1) return n;
8 return fibonacci(n - 1) + fibonacci(n - 2);
9}
10
11// Function: checks if a number is prime
12int is_prime(int n) {
13 if (n < 2) return 0;
14 for (int i = 2; i * i <= n; i++) {
15 if (n % i == 0) return 0;
16 }
17 return 1;
18}
19
20// Function: swap two integers using pointers
21void swap(int *a, int *b) {
22 int temp = *a;
23 *a = *b;
24 *b = temp;
25}
26
27int main(void) {
28 // Call functions
29 printf("fibonacci(10) = %d\n", fibonacci(10));
30
31 for (int i = 1; i <= 20; i++) {
32 if (is_prime(i)) {
33 printf("%d is prime\n", i);
34 }
35 }
36
37 int x = 5, y = 10;
38 swap(&x, &y); // Pass addresses
39 printf("x=%d, y=%d\n", x, y); // x=10, y=5
40
41 return 0;
42}
🔥

pro tip

C passes all function arguments by value — the function receives a copy. To modify the original variable, pass a pointer (address) to it. This is why swap() above takes int *a instead of int a.
Introduction to Pointers

Pointers are the most powerful and feared feature of C. A pointer is a variable that stores the memory address of another variable. Pointers enable dynamic memory allocation, efficient array traversal, and pass-by-reference semantics. They are the reason C can be both portable and low-level.

pointers-intro.c
C
1#include <stdio.h>
2
3int main(void) {
4 int x = 42;
5 int *p = &x; // p stores the address of x
6
7 printf("Value of x: %d\n", x);
8 printf("Address of x: %p\n", (void *)&x);
9 printf("Value of p: %p\n", (void *)p);
10 printf("Dereferenced p: %d\n", *p); // Follow the pointer
11
12 *p = 100; // Modify x through the pointer
13 printf("New value of x: %d\n", x); // 100
14
15 return 0;
16}
Pointer Anatomy
int x = 42; ┌──────────┐ │ 42 │ ← x holds the value 42 └──────────┘ address: 0x7fff5c int *p = &x; & = address-of operator ┌──────────┐ │ 0x7fff5c │ ← p holds the address of x └──────────┘ *p = 42 * = dereference operator (follow the pointer)
What You Will Learn

This documentation covers C from absolute beginner to advanced systems programming. Each section builds on the previous one. Work through them in order for the best learning experience.

SectionLevelTopics
Variables & Data TypesBeginnerPrimitive types, sizeof, constants, type qualifiers
OperatorsBeginnerArithmetic, logical, bitwise, precedence
Control FlowBeginnerif/else, switch, loops, break, continue, goto
FunctionsBeginnerDeclaration, scope, recursion, pass-by-value
ArraysIntermediate1D, 2D, multi-dimensional, array operations
StringsIntermediateChar arrays, string functions, I/O, buffer safety
PointersIntermediateAddress-of, dereference, arithmetic, arrays & pointers
Dynamic MemoryIntermediatemalloc, calloc, realloc, free, leaks
Structures & UnionsIntermediatestruct, union, enum, typedef, nested structures
File I/OIntermediatefopen, fread, fprintf, binary I/O, file positioning
PreprocessorIntermediate#include, #define, macros, conditional compilation
Bitwise OperationsAdvancedAND, OR, XOR, shifts, bit masks, practical uses
Multi-file ProgramsAdvancedHeaders, extern, static, Makefiles, separate compilation
Advanced PointersAdvancedFunction pointers, void*, pointer-to-pointer, arrays
Data StructuresAdvancedLinked lists, stacks, queues, trees, hash tables
Memory ManagementAdvancedStack vs heap, layout, buffer overflow, debugging
C Standard LibraryAdvancedstdio, stdlib, string, math, ctype, time
Type SystemAdvancedCasting, conversions, volatile, restrict, alignment
Modern C (C11/C17/C23)AdvancedThreads, atomics, VLAs, _Generic, constexpr
Debugging & TestingAdvancedGDB, Valgrind, AddressSanitizer, unit tests
Best PracticesExpertCoding standards, common mistakes, security, optimization
$Blueprint — Engineering Documentation·Section ID: C-GETTING-STARTED·Revision: 1.0