The First Week Reset

A 7-day plan to convert “I used to know C” into “I know C well enough to move to Phase 1.” Each day is 90-150 minutes; that fits your 10-15 h/week envelope with margin. Every day has a build, a read, and a checkpoint. If a checkpoint fails, do not move on — re-do the day. This is a reset, not a race.

You have a full-time job at Zoho. If a work day eats a study day, roll the plan over by one day. Miss no more than two days total in the week.

Day 1 (~2 h) — Hello, Toolchain

Build:

// hello.c
#include <stdio.h>
int main(void) {
    printf("hello, %s\n", "world");
    return 0;
}

Compile it four ways and inspect each output:

cc -E hello.c -o hello.i    # look at the top 40 lines with less
cc -S hello.c -o hello.s    # find the _main label
cc -c hello.c -o hello.o    # nm hello.o
cc hello.c -o hello         # ./hello

Read: 01_compiler_toolchain.md — the pipeline table and the flag set.

Checkpoint: you can, out loud, explain what each of .i, .s, .o contains and which flag produced it. If not, re-read.

Day 2 (~2 h) — argc/argv and stdin

Build: echo.c that prints its arguments one per line, then a version that reads stdin until EOF and echoes it.

#include <stdio.h>
int main(int argc, char **argv) {
    for (int i = 1; i < argc; i++) puts(argv[i]);
    return 0;
}

Then add stdin reading with fgets into a fixed buffer. Deliberately compile with -Wall -Wextra -Wpedantic -Werror; fix any warnings.

Read: man pages for puts, fgets, printf. Yes, man 3 printf. Get comfortable with man pages this week; they are the fastest reference for the standard library.

Checkpoint: your echo behaves the same as /bin/echo for simple inputs. You know why argv[0] is the program name.

Day 3 (~2 h) — Make

Build: turn Day 2’s echo into a Makefile-driven project.

project/
├── Makefile
├── src/
│   ├── main.c
│   └── util.c
└── include/
    └── util.h

util.h declares one function like void print_lines(int argc, char **argv);. util.c implements it. main.c calls it. Use the Makefile template from 02_build_systems.md.

Read: 02_build_systems.md — the whole file, slowly. Type the Makefile by hand. No copy-paste.

Checkpoint: make builds. make clean && make builds. Editing util.h triggers a rebuild of both main.o and util.o (proves -MMD -MP is working).

Day 4 (~2 h) — gdb / lldb Break-Step-Print

Build: take the Day 3 project, compile with -g -O0 -fsanitize=address,undefined. Fire up lldb ./build/app (mac) or gdb ./build/app (linux). Run through these motions until they’re smooth:

  1. Set a breakpoint at main.

  2. Run.

  3. bt — see one frame.

  4. Step into print_lines.

  5. fr v / info args — inspect argc, argv.

  6. Print argv[1].

  7. finish to return to main.

  8. continue to exit.

Do this five times. Speed matters — you want it in your fingers.

Read: 03_debugging_stack.md — the top-20 table.

Checkpoint: you can name 10 gdb/lldb commands from memory without looking at the file.

Day 5 (~2 h) — assert() and the First Segfault

Build: write a divide.c that takes two ints from argv, converts them with atoi, and prints the quotient. Add assert(b != 0). Trigger the assert, see it fire. Then remove the assert, run ./divide 10 0, see what happens (SIGFPE, not a segfault — instructive).

Now write segfault_1.c:

#include <stdio.h>
int main(void) {
    int *p = NULL;
    *p = 42;
    return 0;
}

Compile without sanitizers first. Run under lldb, get the crash, bt. Recompile with -fsanitize=address and run — notice how much more informative the ASan output is (file, line, what kind of access).

Read: man assert, and the ASan section of 03_debugging_stack.md.

Checkpoint: you understand the difference between a signal (SIGSEGV, SIGFPE, SIGABRT), an assertion failure (which raises SIGABRT), and a UBSan/ASan report (which prints then aborts).

Day 6 (~2 h) — The Segfault Zoo (start of Project 2)

Build: create projects/segfault_zoo/ with five files, one per segfault type. See projects.md for the full spec. Today, do the first two: null deref (from Day 5) and stack overflow via infinite recursion. For each, produce:

  • The .c file that reproduces the crash.

  • A short NOTES.md (5-10 lines): what triggers it, what gdb shows, what ASan shows, how you’d fix it in real code.

Read: search r/C_Programming for “biggest mistake learning C” — read three top posts. You’ll see the same advice everywhere: enable warnings, use sanitizers, don’t skip pointer arithmetic exercises.

Checkpoint: you have two working repro cases in projects/segfault_zoo/ and can explain each crash in one sentence.

Day 7 (~2 h) — Finish the Zoo + Reflect

Build: the remaining three segfaults: use-after-free, heap out-of-bounds, double-free. For each write the same NOTES.md. Verify all five compile clean with -Wall -Wextra -Wpedantic -Werror (they should — being buggy at runtime is different from being non-compliant).

Read: re-read 01_compiler_toolchain.md end to end. Different bits will land this time.

Checkpoint (the big one):

  • All five segfaults reproduce and produce ASan output.

  • You can, from a cold prompt, in under 60 seconds: create a new foo.c, write hello world, compile with the strict flag set, run, break in lldb at main, step, print, exit.

  • Your Makefile template is committed somewhere you can copy-paste it from for the next 12 months.

If all three are true, you are done with Week 1. Weeks 2-4 finish the two projects in projects.md and polish your editor setup. If any are false, spend Week 2’s first day fixing the gap; do not move on with a broken foundation.

What Most People Get Wrong About the First Week

They rush. C is small — the language spec is <phone_number_or_numberic_id_or_random_id_26> pages depending on the standard, versus C++’s 1800+ — and it looks tractable, so people cram Week 1 into two evenings. The result is superficial fluency: they can write hello world but not read a linker error. Spend the full seven days. Every hour you invest in reflex (compile-run-debug muscle memory) now, saves you five hours of frustration in Phase 2 when the projects get harder.

The second failure mode: skipping the segfault zoo because it feels like busywork. It is not busywork. Reproducing a use-after-free and watching ASan pinpoint it teaches you more about C’s memory model than a chapter of any book. Do the zoo.


Return to README.md · Next: 05_editor_setup.md