Getting Started

Course 1 · Ch 1
Getting Started
The language every "manual control" tradeoff on this site has ultimately been measured against

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.

gcc --version # gcc (Ubuntu 13.2.0) 13.2.0

The Smallest C Program

#include <stdio.h> int main() { printf("Hello, C!\n"); return 0; }

#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

gcc hello.c -o hello ./hello # Hello, C!

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.

Forgetting -o produces a.out
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.

ConceptRustC
Compile & runcargo run (one step)gcc file.c -o out && ./out (two steps)
Toolchain managerrustup (official, singular)none — gcc or clang, your choice
Package managercargo + crates.ionone official — make/CMake handle builds only
Print a lineprintln!(...)printf("...\n")
Entry pointfn main()int main()
"Manual control" starts at the toolchain, not just memory
Rust's whole pitch was refusing the memory-safety tradeoff C accepts. But notice this chapter never even reached memory yet — C already trusts the programmer to choose a compiler, name an output file, and assemble a build process by hand. The same "no safety net, no guardrails" philosophy that governs C's memory model (Course 2's own central chapter) governs its tooling too.

Coding Challenges

Challenge 1

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 solution
Challenge 2

Compile a program without the -o flag. Identify the name of the resulting executable, then run it directly by that name.

📄 View solution
Challenge 3

Explain, 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 solution

Chapter 1 Quick Reference

  • Compile-then-link: two conceptually separate steps, usually run together by one gcc command
  • gcc / clang — no single official compiler, unlike Rust's rustc
  • #include <stdio.h> — pulls in library declarations; printf is an ordinary function, not a keyword
  • int main() { ... return 0; } — the entry point; the explicit return value matters
  • gcc file.c -o name — always name the output; omitting -o produces a.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