Declaration vs Definition
The greenhouse logger has grown into two files: sensor.c counts readings, and main.c prints the count at the end of the day. When the compiler works on main.c, it has never seen sensor.c. So how does main.c know that reading_count exists, and what type it has? The answer is the difference between announcing a name and creating it.
The rule
A declaration introduces a name; a definition makes it real.
A declaration tells the compiler "this name exists, and here is its type". A definition also creates the thing: storage for a variable, or the body of a function.
/* sensor.c */
int reading_count = 0; /* definition: storage is created here */
/* main.c */
extern int reading_count; /* declaration: it lives somewhere else */Functions follow the same pattern. A prototype is a declaration; the version with a body is the definition:
double average(int total, int count); /* declaration (prototype) */
double average(int total, int count) /* definition */
{
return (double)total / count;
}Three rules hold it together:
- Every definition is also a declaration, but not every declaration is a definition.
- You may declare a name many times, as long as every declaration agrees on the type.
- A name the program uses must be defined exactly once in the whole program.
Inside a function, int hour; is a definition: it creates storage for hour, even though it gives it no value yet.
Why declare at all? The compiler reads each file top to bottom. If main calls average before any declaration of it appears, modern C compilers reject the call (C99 removed the old rule that guessed a declaration for you). A prototype near the top, or in a header, solves it. That is exactly what #include <stdio.h> did in your first program: it pasted in the declaration of printf, while the definition lives in the C library.
The shortcut
Ask: "Does this line create storage or code?" Yes means definition. If it only states a type, it is a declaration. Two quick tells for a declaration: extern with no initializer, and a function header that ends in ; instead of {.
extern int reading_count;externand no value: it only announces the name. Declaration.
Drills
Answer fast — trust the rule.
What is extern int reading_count; at file scope?
What is double average(int total, int count);?
Inside main, what is int hour;?
How many definitions of reading_count may a program that uses it contain?
At file scope, what is extern int limit = 30;?
Remember
- A declaration introduces a name; a definition makes it real.
- Shortcut: "does this line create storage or code?"
externwith no value, or a header ending in;, is only a declaration. - Trap: declare many times, define exactly once, and declare functions before you call them.
