Getting Started
rust1-1 opened by naming the tradeoff Rust refuses to accept: manual-control performance without manual-control memory bugs. C is the language that tradeoff was named against — no garbage collector, no borrow checker, no compiler enforcing safety at all. Just the programmer, trusted completely. This course starts exactly where that trust begins.
The Compile-Then-Link Model
C has no virtual machine and no interpreter — source code becomes a real, standalone executable in two genuinely separate steps. Compilation turns each .c file into an object file (machine code, but not yet a runnable program). Linking then combines every object file, plus any libraries being used, into one final executable. A single gcc command usually runs both steps back to back — but they remain conceptually distinct, and Chapter 5 of Course 2 (Multi-File Projects) is built entirely around treating them as such.
Installing a Compiler: gcc and clang
Unlike Rust's rustup — one official installer managing one official toolchain — C has no single canonical compiler. gcc (GNU Compiler Collection) and clang (LLVM's compiler) are the two most common; both compile standard C, both are genuinely widely used, and neither is "more official" than the other the way rustc is for Rust.
The Smallest C Program
#include <stdio.h> pulls in the standard I/O library's declarations — printf isn't a language keyword, it's an ordinary library function, declared in that header. int main() is the entry point, same role as Rust's fn main() — but notice the explicit return 0;: C's main reports a real exit status back to the operating system, and leaving it out (pre-C99) was undefined behavior, a theme this course returns to often.
Compiling & Running
There is no single-command equivalent of cargo run or go run — compiling and running are always two separate commands. -o hello names the output executable explicitly.
gcc hello.c with no -o flag silently compiles to a file named a.out — a genuine, still-common beginner surprise. Always name the output explicitly.
No Built-In Package Manager or Build Tool
This is the first real toolchain difference from both Rust and Go. Go's toolchain is minimal but complete — go build handles everything. Rust bundles even more into cargo — building, dependencies, testing, all official. C has none of this as an official standard: no built-in package registry, no single blessed build tool. Third-party tools like make (Course 2's own Chapter 5) and CMake exist and are genuinely widely used — but nothing plays the role cargo plays for Rust. This isn't an oversight; C predates the very idea of a language-integrated package manager by decades.
| Concept | Rust | C |
|---|---|---|
| Compile & run | cargo run (one step) | gcc file.c -o out && ./out (two steps) |
| Toolchain manager | rustup (official, singular) | none — gcc or clang, your choice |
| Package manager | cargo + crates.io | none official — make/CMake handle builds only |
| Print a line | println!(...) | printf("...\n") |
| Entry point | fn main() | int main() |
Coding Challenges
Write a C program that prints your name and a short greeting using two separate printf calls. Compile it with gcc, explicitly naming the output file, and run it.
📄 View solutionCompile a program without the -o flag. Identify the name of the resulting executable, then run it directly by that name.
📄 View solutionExplain, in your own words, why C having no official package manager or build tool is a genuinely different situation than Rust or Go — not simply "C is missing a feature," but a real consequence of when and why the language was designed.
📄 View solutionChapter 1 Quick Reference
- Compile-then-link: two conceptually separate steps, usually run together by one
gcccommand - gcc / clang — no single official compiler, unlike Rust's
rustc #include <stdio.h>— pulls in library declarations;printfis an ordinary function, not a keywordint main() { ... return 0; }— the entry point; the explicit return value mattersgcc file.c -o name— always name the output; omitting-oproducesa.out- No official package manager or build tool —
make/CMake fill that gap unofficially, covered in Course 2 - Next chapter: variables, basic types, and why the standard doesn't fix their exact sizes