Last 30 Days
No notifications
C is a compiled, low-level, general-purpose programming language created by Dennis Ritchie at Bell Labs in 1972. It is the language Linux, Windows kernels, Git, Redis, SQLite, Python's interpreter, and most of your phone's firmware are written in.
If you learn C, you understand how every other language actually works under the hood.
| Reason | What it gives you |
| Closest to the machine | You see memory, addresses, and bytes directly |
| Foundation of CS | Pointers, stack, heap, compilation — the real CS concepts |
| Tiny and explicit | Only ~32 keywords. Nothing is hidden from you |
| Universal | Runs on every device with a CPU, from microwaves to supercomputers |
| Competitive edge | Fast, predictable — used in Olympiad, ICPC, embedded interviews |
1. A C compiler — gcc (Linux/Mac) or MinGW / MSVC (Windows)
2. A text editor — VS Code is perfect (install the "C/C++" extension)
3. A terminal to compile and run
Verify your setup:
gcc --versionIf you see a version number, you're ready.
#include <stdio.h>int main(void) {
printf("Hello, world!\n");
return 0;
}
Save as hello.c, then in your terminal:
gcc hello.c -o hello
./helloOutput:
Hello, world!| Line | What it means |
#include | Bring in the standard input/output library so we can use printf |
int main(void) | Every C program starts here. Returns an int to the operating system |
{ ... } | Curly braces group statements into a block |
printf("..."); | Print text to the console. \n is a newline |
return 0; | Tell the OS "the program finished successfully" |
> Important: C is case-sensitive. Main is not main. Every statement ends with ;.
C is older than most of your professors and still runs the world. The Linux kernel, your Wi-Fi router, the firmware in your car, the engines of Python and JavaScript — all written in C. Learning it is like learning the alphabet of computing.
C is a statically-typed, compiled, procedural language with manual memory management.
.c file is translated by a compiler (gcc/clang/MSVC) into machine code that the CPU runs directly. There is no interpreter sitting between you and the hardware.malloc, you give it back with free. The language trusts you.Four invisible stages happen between gcc hello.c and ./hello:
1. Preprocessing — handles #include, #define (text substitution)
2. Compilation — turns C into assembly for your CPU
3. Assembly — turns assembly into object file (.o) — raw bytes
4. Linking — glues your .o + standard library .o → executableYou can stop at any stage:
gcc -E hello.c # preprocessor output only
gcc -S hello.c # produces hello.s (assembly)
gcc -c hello.c # produces hello.o (object file)
gcc hello.c -o hello # full pipeline → executableThe first time you run -S and look at the assembly, the magic dies in the best possible way: you realise this is what every program eventually becomes.
#include <stdio.h> // 1. headers (libraries)int main(void) { // 2. entry point
// 3. your code
return 0; // 4. exit status
}
Memorise this shape. You will type it thousands of times.
#include is not an importIt is literally text substitution. The preprocessor opens stdio.h and pastes its contents into your file before the compiler ever sees it. That's why headers can declare functions but should not define them — every file that includes the header would get a duplicate.
int main(void) — the contractmain is the function the operating system calls when you run your program. It returns an integer:
0 → successecho $? on Linux/Mac) — useful for scripts.printf — print formattedprintf is not a keyword, it's a regular function from stdio.h. You hand it a format string and (optionally) values to plug in:
printf("Hello, %s! You are %d years old.\n", "Alice", 19);
// Hello, Alice! You are 19 years old.| Specifier | Means | Example |
%d | integer | 42 |
%f | float / double | 3.14 |
%c | single character | 'A' |
%s | C-string | "hello" |
%x | hex | ff |
\n | newline | (line break) |
\t | tab | (tab) |
If your format string says %d but you pass a string, the program does not warn you — it crashes or prints garbage. C trusts you.
// single-line comment (C99 onwards, universal today)/*
multi-line
comment
*/
Comments are stripped by the preprocessor — the compiler never sees them.
Windows
1. Install MSYS2 from msys2.org, then pacman -S mingw-w64-x86_64-gcc
2. Or install MinGW-w64 and add its bin to PATH
3. Verify: gcc --version
macOS
xcode-select --installThat gives you clang (which understands the same flags as gcc).
Linux
sudo apt install build-essential # Debian / Ubuntu
sudo dnf install gcc # FedoraEditor: VS Code + the official "C/C++" extension. Optional: "Code Runner" so you can hit a button to compile and run.
Your day will look like this:
gcc main.c -o main && ./mainThe && runs ./main only if compilation succeeded. Wrap it in a shell alias and your iteration speed triples.
Add warnings from day one:
gcc -Wall -Wextra -std=c11 main.c -o main| Flag | Why |
-Wall | Turn on common warnings |
-Wextra | Turn on extra warnings |
-std=c11 | Use the C11 standard (modern, widely supported) |
-o name | Name the output file |
-g | Add debug symbols (for gdb) |
-O2 | Optimise (use for release builds) |
Treat warnings as errors. They are almost always real bugs.
1. Forgetting the semicolon. Every statement ends with ;. Missing one → 30-line error message.
2. Mismatched braces. Use an editor that matches { and } for you.
3. Calling printf without #include . The compiler complains about an "implicit declaration".
4. Using = when you meant ==. if (x = 5) assigns 5 to x and is always true. Bug.
5. Mixing tabs and spaces. Pick one. Modern editors handle this automatically.
6. Ignoring warnings. "It compiles" ≠"it works". Warnings catch real bugs.
You have a compiler, a Hello World, and a mental model of how C runs. Next up: variables and data types — how C stores numbers, characters, and decisions in memory.