Your first C program
Install a C compiler, write a main function, call printf, and compile and run your first C program with gcc.
- Install gcc and verify it with gcc --version
- Write a C program with a main function and a printf call
- Compile a C source file into an executable with gcc
- Run the resulting binary and read a compiler error message
Before you can write C programs, you need a C compiler. The most widely used one is gcc — the GNU Compiler Collection. It is free, works on Linux, macOS, and Windows (via WSL or MinGW), and is what most tutorials, textbooks, and production systems use.
Installing a compiler
Linux: gcc is often pre-installed. If not: sudo apt install gcc (Debian/Ubuntu) or sudo dnf install gcc (Fedora).
macOS: Install the Xcode Command Line Tools: xcode-select --install. This gives you clang aliased as gcc — it is compatible and will work for everything in this track.
Windows: Install WSL 2 (Windows Subsystem for Linux) and run sudo apt install gcc inside it. This gives you a real Linux environment and is the recommended path.
Verify the installation:
gcc --versionYou should see something like gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0. The exact version does not matter much for what this track covers.
The minimum C program
Create a file called hello.c. The .c extension is the convention for C source files.
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
return 0;
}This is the smallest complete C program that does something visible. Five things to understand:
#include <stdio.h> is a preprocessor directive. Before compilation starts, the preprocessor reads this line and pastes the contents of the system header file stdio.h into your source. That header declares the printf function — without the include, the compiler would not know printf exists.
int main(void) is the entry point. Every C program starts execution here. The int return type tells the OS whether the program succeeded (0) or failed (non-zero). The void in the parameter list means "this function accepts no arguments." You will also see int main(int argc, char *argv[]) when you need to read command-line arguments.
printf("Hello, World!\n") prints a string to standard output. The \n is the escape sequence for a newline character. Without it, the terminal prompt appears on the same line as your output.
return 0 exits the program and tells the OS the program succeeded. A non-zero return value signals failure — by convention, different values mean different kinds of failure. This feeds into shell scripting, where you can check $? after running a command.
Semicolons end statements. Unlike Python, C does not use indentation or newlines to separate statements — it uses semicolons. Forgetting one is one of the most common beginner mistakes and the compiler will tell you precisely where.
Compiling and running
gcc hello.c -o hello
./hellogcc hello.c compiles the source file. -o hello names the output file hello (without -o the output is named a.out by default). ./hello runs it.
Output:
Hello, World!Always compile with warnings enabled. Add -Wall -Wextra to your gcc command to enable most useful warnings. Example: gcc -Wall -Wextra hello.c -o hello. Warnings are not errors, but they point to real bugs. Get into the habit of writing code that produces zero warnings.
Reading a compiler error
Type a deliberate mistake — remove the semicolon after the printf line:
#include <stdio.h>
int main(void) {
printf("Hello, World!\n")
return 0;
}Compile:
hello.c:5:5: error: expected ';' before 'return'
5 | return 0;
| ^~~~~~The format is file:line:column: severity: message. Here, hello.c line 5 column 5 is where the compiler noticed the problem. The actual missing semicolon is at the end of line 4 — the compiler reports where it first realized something was wrong, which is usually the token after the mistake.
The first error is the most useful. When gcc prints many errors, they often cascade from a single root cause. Fix the first error, recompile, and see if the rest disappear. Chasing the tenth error while the first is still unresolved is a common trap.
The compilation pipeline
When you run gcc hello.c -o hello, four things happen in sequence:
- Preprocessing:
#includedirectives are expanded,#definemacros substituted. - Compilation: C source is translated to assembly language.
- Assembly: assembly is translated to machine code (object files).
- Linking: object files and libraries are combined into the final executable.
You do not need to invoke each step separately — gcc handles all of them. But knowing the stages matters for understanding error messages: a "linker error" is different from a "compiler error," and fixing them requires different actions. The Advanced tier covers this in depth.
A slight improvement
Add a newline print to see how multiple calls work:
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
printf("This is C.\n");
return 0;
}Compile and run. Notice that printf is called once per line — it does not automatically add a newline. This is intentional: sometimes you want to build up a line of output piece by piece.
Where to go next
You have a working compiler and understand the basic structure of a C program. Next: variables and primitive types — how C stores data, what int, char, float, and double mean, and how to declare variables.
What is C and why it matters
Learn why C remains the most influential systems programming language and what makes it uniquely valuable to understand.
Variables and primitive types
Learn how C stores data with int, char, float, and double — including sizes, ranges, and how to print values with printf format specifiers.