Your First C Program
A C program is small enough to hold in your head when you know what every line promises. In this lesson, you will write a complete source file, run it, observe its terminal output, respond to a compiler message, and make a small program of your own.
Build one reliable mental template
Start with a complete source-file template
Begin with the smallest program that has a real purpose: it produces a line of terminal output and reports that it finished normally. Copy the structure into a file called hello.c, then change the greeting before you run it. The browser runner uses a safe beginner subset; a local compiler is still the authority for real C code.
Create a complete hello.c
Change the greeting inside the quotes. Predict the exact terminal line, then run the source and compare the output with your prediction.
Edit the program, predict its output, then run it.
Read the shape before reading the words
A first program is easier to debug when you separate its roles. The directive at the top prepares declarations for the compiler. The function header defines where the program starts. Braces mark the body of that function. Ordinary statements inside the braces end with semicolons. The final return statement communicates an exit status to the environment.
Prepare output declarations
Headers give your source declarations for library facilities. Because this program uses puts and printf, it includes the standard input/output header before main.
State the entry function
In a normal hosted program, the runtime begins at main. This form returns an integer status and accepts no parameters.
Group the program body
Opening and closing braces define the body of main. They express structure, not the end of every individual instruction.
End each instruction
A semicolon completes ordinary C statements such as an output call or return 0;. Forgetting one changes how the compiler reads the next line.
Use comments and order to make intent visible
C runs the statements in main in order, from top to bottom, unless you later add control flow. Comments are ignored by the compiler, so use them to explain a decision or a non-obvious constraint—not to repeat what a clear line already says. Run this source, then move one output call and predict how the terminal order changes.
Trace a linear program
The runner ignores both line and block comments, just as a compiler does. Focus on the order of the two output calls.
Edit the program, predict its output, then run it.
Choose an output call on purpose
puts is ideal for one plain line of text: it writes the string and adds a newline. printf gives you more control: it follows the format string exactly, so you place \n where a new terminal line belongs. Later, printf will also display values; for now, use it to make the newline rule visible.
Compare puts and printf
Run the program first, then remove one newline escape from a printf call and observe which output fragments join together.
Edit the program, predict its output, then run it.
Build the source on your machine
Save the source as hello.c. Building from a terminal makes the source-to-executable boundary concrete: the compiler reads the file, reports warnings or errors, and produces a program you can start. Use warning flags from the beginning so suspicious code is visible before it becomes a habit.
xcode-select --installclang -Wall -Wextra -Wpedantic hello.c -o hello./hellogcc -Wall -Wextra -Wpedantic hello.c -o hello./helloIf gcc is unavailable, install your distribution’s compiler or build-essential package first.cl /W4 hello.chello.exeToolchain installation differs, but the reliable loop stays the same: compile, read diagnostics, then run the executable.Finish with a meaningful status
When your program reaches return 0;, it returns a conventional success status to the shell or operating system. That status is separate from the terminal text. A program can print a friendly message and still return a non-zero status to signal a failure; you will use those distinctions more deliberately once branches and errors arrive later in the course.
Repair the missing statement boundary
This source has one missing semicolon. The compiler—or the safe lesson runner—cannot know where the puts statement stops before it sees return. Read the message, inspect the previous line, add only the semicolon, and run it again.
Repair one missing semicolon
Make the smallest possible change. The goal is not to guess; it is to connect the diagnostic to a precise source boundary.
Edit the program, predict its output, then run it.
Independent lab: publish a terminal event card
Build a three-line terminal announcement without copying an earlier message. Keep the include directive, main signature, braces, and return 0;. Change the event name, add a plain line with puts, and add a formatted line with printf that ends with \n. Run the result and explain why each terminal line appears where it does.
Build a three-line announcement
Use the starter as a structural template, but write your own event information. Make the terminal output easy for a person to scan.
Edit the program, predict its output, then run it.
Lesson review
You can now read a complete C source file as a set of small contracts: the header prepares declarations, main defines the entry point, braces create the body, semicolons complete statements, output calls create terminal text in order, and return 0; reports normal completion. That is enough structure to begin adding values in the next lesson without treating the program as unexplained punctuation.
- I can write the smallest complete source file that includes output,
main, and a success status. - I can explain the different jobs of braces, parentheses, semicolons, and newline escapes.
- I can predict output order and choose between
putsandprintffor a plain line. - I can compile with warnings enabled, use a diagnostic to find a missing semicolon, and make one targeted repair.