In this lesson:
- what "source code" actually is, and what your computer does with it
- the three stages every C program passes through: edit, compile, run
- why a compile step exists at all (and what languages skip it)
- how to read a "hello, world" file line by line
- the small set of commands you'll type thousands of times
A program is just text, until it isn't
Open a .c file in any editor and you'll see characters: letters, brackets, semicolons. That is the source code. Your CPU cannot execute those characters directly, it only understands numeric instructions wired into its silicon.
Bridging that gap is what a compiler does. It reads your text file and produces a different file made of CPU instructions, called an executable (or "binary"). When you run the executable, the operating system loads it into memory and tells the CPU to start executing from a known entry point.
So a program lives in three forms at three moments:
hello.c hello (executable) running process
─────── ───────────────── ────────────────
text you type → bytes the CPU runs → instructions
actually executing
│ │ │
"source" "compiled" "running"The minimum C program
Here is a complete program. Every line is doing real work; nothing is decoration.
#include <stdio.h> // pull in printf and friends
int main(void) { // execution starts here
printf("hello, world\n");
return 0; // 0 means "ran successfully"
}Line by line:
#include <stdio.h>, pastes in the declaration ofprintfso the compiler knows how to call it. Without this line the compiler complains.int main(void),mainis the entry point the operating system calls when your program starts. Theintsays it returns an integer;voidsays it takes no parameters.printf("hello, world\n");, prints the string. The\nis a newline character; without it, the cursor stays glued to the end of the line.return 0;, hands an integer back to the OS. Convention:0means success, anything else means an error.
The compile / run loop
The full cycle in a terminal:
$ gcc hello.c -o hello # compile: text → executable
$ ./hello # run: ask the OS to execute it
hello, world
$ echo $? # check the return code from main()
0A picture of what just happened:
flowchart LR
A[hello.c<br/>source text] -->|gcc| B[hello<br/>executable]
B -->|./hello| C[Running<br/>process]
C -->|return 0| D[Exit code<br/>back to shell]You will run that two-step cycle (compile, then run) thousands of times across your career. Get comfortable with it now.
Compiled vs interpreted, and why it matters
C is compiled: you translate the whole file ahead of time, once, into a binary that runs at native CPU speed. Python and JavaScript are interpreted: there is no separate compile step you run by hand; an interpreter reads your source and executes it on the fly.
| Compiled (C, C++, Rust) | Interpreted (Python, JS) | |
|---|---|---|
| Build step | Yes, must compile before running | No, just run the source |
| Run-time speed | Native CPU speed | Slower, often 10-100× |
| Errors caught early | Many, at compile time | Most show up only at run time |
| Output | Standalone executable | Needs the interpreter installed |
Embedded systems live in the compiled world for two reasons: a microcontroller has no interpreter sitting in flash waiting to run Python, and the predictability of native code is essential when timing matters. That is why this course is in C.
Gotchas
- Forgetting to recompile. You edit
hello.c, then run./helloand see the old behavior. Easy bug: you ran the old binary because you skippedgcc. Always recompile after editing. - Missing semicolons. Every C statement ends with
;. The error message often points to the line after the missing one, because the compiler only notices the problem when it hits unexpected tokens. - Missing
\n.printf("hello")produces no visible output on some terminals until the next newline arrives. Always end lines you print with\n. - Confusing
main's return withprintf's output.return 0;does not appear on screen. It is a number passed to whoever started the program. Useecho $?(Linux/macOS) to see it.
TL;DR
- A program starts as text (source), becomes a CPU-runnable binary (compile), and finally runs as a process.
- In C,
mainis where execution starts. Returning0means success. - The everyday loop is two commands:
gcc file.c -o namethen./name. - Compiled languages catch errors earlier and run faster, the tradeoff is an extra build step you must remember to perform.