The Anatomy of a C Program
The sections of a C source file, what main is, printing with printf, and compiling and running your first program with gcc.
Every C Program Has the Same Skeleton
Exam papers love the question "explain the structure of a C program", and for once the exam and the working programmer agree: it is worth knowing cold, because every C file you will ever read hangs off the same skeleton. Here it is, annotated:
Four sections, top to bottom: a documentation comment, the include lines, the definition of main, and inside it the statements. Let us take the skeleton apart bone by bone.
Comments
Anything between /* and */ is a comment: the preprocessor removes it before the compiler ever looks at the code. Comments exist for the human reader. A comment can span several lines, which is why the closing */ matters; forget it and the compiler will swallow your code until the next */ it finds, with confusing errors to match.
Comments do not nest. The search for the closing */ is not clever: it stops at the first one it finds, no matter how many /* it passed on the way. So this line does not comment itself out the way it appears to:
/* outer /* inner */ still comment? */
The comment ends at the first */, which leaves still comment? */ sitting in your program as code. The compiler says so twice, once as a hint and once as the real complaint:
warning: '/*' within comment [-Wcomment]
error: unknown type name 'still'
The practical consequence: you cannot switch off a block of code by wrapping it in /* ... */ if it already contains a comment. The preprocessor has a proper tool for that, and chapter 14 introduces it.
Remember from the last lesson: this course speaks ANSI C, so // comments are a compile error here. Write /* ... */.
The Include Section
#include <stdio.h>
stdio.h is a header: a file describing the standard input and output functions, printf among them. The #include pastes it in so the compiler knows exactly what printf looks like before you call it. The angle brackets mean "search the system's standard locations". Every program in this course that prints anything starts with this line.
The main Function
int main(void)
Execution starts at main. The operating system calls it when your program launches, and your program lives exactly as long as main is running. Read the line inside out:
mainis the function's name, and it is not negotiable; the linker looks for this exact name.(void)saysmaintakes no arguments. In C, empty parentheses()mean "unspecified arguments", which switches off checking, so(void)is the correct way to say "none". This is a real difference from C++ and a classic exam trap.- The leading
intsaysmainhands an integer back to the operating system when it finishes.
Old textbooks and old exam answers write void main(). The standard says main returns int, and always has; void main() is a non-standard habit that some old compilers tolerated. On this platform it will not compile, and in an exam answer int main(void) is never wrong.
The Body: Braces and Statements
The braces { and } bound the function's body: the statements that run, in order, top to bottom. Each statement ends with a semicolon. The semicolon is the terminator, not a separator, so the last statement needs one too.
printf("part one\n");
printf prints the text between the quotes: a string literal. The \n inside it is an escape sequence, a two-character code for one unprintable character, here the newline that moves the cursor to the next line. Without it, the next printf continues on the same line. Try deleting one \n in the runnable example above and watch the two parts collide.
A few escape sequences worth knowing now: \n newline, \t tab, \" a literal double quote inside a string, \\ a literal backslash.
C Is Free-Form
The compiler does not read lines. It reads a stream of tokens: names, keywords, numbers, strings, punctuation. Whitespace, meaning spaces, tabs, and newlines, exists only to keep one token from running into the next, and wherever it is not needed for that it is invisible. This is what makes C a free-form language: your indentation, blank lines, and brace placement are for human readers, not for the compiler.
So one statement may be spread across several lines, and several statements may share one line:
a = 2; b = 3;
Pushed to the limit, a whole program fits on a single line. What follows is legal C, compiles without a warning under this course's strict flags, prints 5, and is exactly what you should never write:
The compiler is perfectly happy. A human trying to find a bug in it is not, and neither is an examiner marking it. Choose the conventional layout instead, the one every example in this course uses: one statement per line, braces lined up, the contents of each block indented one level.
The freedom has one hard limit. Whitespace may go between tokens but never inside one: int cannot be typed as in t, and printf cannot be typed as pri ntf, because each would then be two tokens instead of one. Comments are freer than that, and may appear anywhere whitespace may, since removing one leaves whitespace in its place.
Free-form layout also explains the first error listed at the end of this lesson. Because the compiler has no notion of where a line ends, a missing semicolon does not stop it at the end of the guilty line; it reads straight on into the following line and complains there.
return 0
return 0;
This is the integer main promised. By convention 0 reported to the operating system means "success" and any non-zero value means "something went wrong"; shell scripts and build tools read this value even when humans never see it. In ANSI C the return is not optional in spirit: if execution falls off the closing brace of main without one, the status returned to the operating system is indeterminate. (The C99 standard later made that case return 0 automatically, which is why some books say the line can be omitted. In this dialect, and in an exam answer, write it.)
How Exam Papers Name the Sections
The skeleton above has four parts because that is all a small program needs. Textbooks and exam papers describe a fuller layout in a fixed order, and "describe the structure of a C program" is asking for these names:
- Documentation section — the opening comment block: what the program does, who wrote it, when.
- Link section — the
#includedirectives naming the library declarations to pull in. - Definition section —
#definedirectives creating symbolic constants (chapter 2). - Global declaration section — variables visible to more than one function, and declarations of the functions themselves (chapter 9).
mainfunction section — itself split into a declaration part, where this block's variables are declared, and an executable part, the statements that run. ANSI C requires that order, which is the next lesson's subject.- Subprogram section — the definitions of the functions you wrote yourself (chapter 9).
Every section except main may be absent when a program has no need of it, which is why anatomy.c above shows only three of the six: documentation, link, and main. Learn the list for the exam question, and expect to meet the other three one at a time as the course reaches them.
What the Machine Does With All This
It is worth connecting the anatomy to the pipeline from the last lesson. The comment and the #include are consumed by the preprocessor. The compiler translates main into machine code and notes that it calls something named printf. The linker finds the compiled printf inside the C standard library and wires the call up. At run time the operating system loads the executable, calls main, your statements execute in order, and the 0 travels back to whoever launched the program.
Common First-Program Errors
Worth meeting deliberately, in the safety of a lesson:
- A missing semicolon: the compiler reports the error on the line after the real mistake, because that is where it noticed something was wrong. When an error line looks innocent, look one line up.
- A missing closing
*/: the rest of the file becomes comment. - Misspelling
printf: old-style C lets the call compile and the linker fails with an undefined reference, exactly as the previous lesson described.
Key Takeaways
- The skeleton is: comment block,
#includesection,int main(void), statements in braces,return 0;. Exam papers name six sections: documentation, link, definition, global declaration,main, subprogram. #include <stdio.h>pastes in the declarations forprintfand friends.- Comments cannot be nested: the first
*/closes the comment, whatever/*came before it. - C is free-form: whitespace between tokens is insignificant, so several statements may share a line and layout is for humans. Whitespace inside a token is not allowed.
(void)means no parameters; bare()means unspecified, which is weaker.void main()is non-standard; writeint main(void).- Statements end in semicolons;
\nis the newline escape sequence, and output stays on one line without it. return 0;reports success to the operating system.
How did you find this lesson?
Your rating helps us improve the content.
Create an account to track your progress and access interactive exercises. Already have one? Sign in.
The Anatomy of a C Program - Quiz
Test your understanding of the lesson.
Practice Exercises
Assemble the Skeleton
Complete a C program so it prints three exact lines. You will need one printf call per line, a \t escape for a tab, and \" escapes to put double quotes inside a string. printf prints exactly what you give it: every newline in the output is one you wrote.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!