In C, the Header File (.h) is the contract. It's the promise you make to the user of your code. In Step 3, we defined this contract before writing a single line of actual code. This is called Interface-First Design.
You'll see this at the top of every header:
#ifndef FILE_NAME_H
#define FILE_NAME_H
...
#endifWhy? This prevents infinite loops or double-definition errors if a file is included more than once.
In scanner.h, we defined:
typedef struct {
const char *source;
size_t current;
} Scanner;By putting this in the header, we let the user see what data they are working with conceptually, but they don't need to worry about managing it manually. We provide scanner_init to handle the setup.
In tokenizer.h, we used enum TokenType. Replacing magic numbers (like returning 1 for a word) with named constants (TOKEN_WORD) makes code readable and less error-prone.
Notice Token uses const char *start?
typedef struct {
const char *start;
int length;
} Token;Engineering Decision: We do NOT copy the string "Hello" into the token. We just point to where "Hello" sits in the original source.
- Pro: Extremely fast. Zero memory allocation.
- Con: The source string must stay in memory while we use the token.
- Contracts: Write headers to define what your code does, separate from how.
- Efficiency: Use pointers to reference data instead of copying it when possible.