In C you don't need to include headers. C (and C++) headers are just a handy place to bung declarations that define the interface to a particular lump of code. They (should) contain the minimum amount of information you need to use a particular object file or library.
Say I'm writing a hello world. Instead of the traditional way I can write:
int main( int, const char ** )
{
int printf( const char *format, ... );
printf( "Hello world!!\n" );
}
and it'll all work swimmingly (on a standard implementation anyway).
The idea behind it is to keep the tools simple. To generate a call to printf the compiler just needs to know what its interface is. If the compiler knows that it can generate a call to the function after setting up the parameters and clean up the stack when the function returns it doesn't have to know anymore about how printf is implemented.
It also keeps the library and object file format simple as well. With this 1970s compile/link model object files are just blobs of binary data with a table of names mapped to offsets into the blob. If you want a more sophisticated model there's no reason you couldn't implement one but you'd pile more stuff into the object file and end up with something like a DLL or Java JAR rather than an object file.
So there are really two main reasons:
- inertia (or tradition) - it's been with us since 1965 or so (Fortran uses a similar model)
- pragmatism - makes it easier to link all sorts of stuff together, including assembly languages to high level languages.
Cheers,
Ash