Function names are a lot like pointers (variables that hold memory addresses) in that they reference the memory location of a function. Like any variable, a function cannot be called prior to it being declared or defined.
Code:
#include <stdio.h>
int main( void )
{
show_message(); /* Wrong */
return 0;
}
void show_message( void )
{
printf( "Hello World\n" );
}
Prior to using the show_message() function, it must either be declared (with a prototype) or defined (by placing the function in the source file before any calls to it). To fix the code example above, either prototype the show_message() function or swap the order of the functions, so that show_message() is above main().
Prototypes are also unnecessary to declare functions that exist in other modules (source files), as the dependency will be resolved when linking the object files together into an executable. Here's an example of a program that uses three source files (note function prototypes are not required):
test1.c
Code:
int main( void )
{
show_message_1( "Hello " );
show_message_2( "World\n" );
return 0;
}
test2.c
Code:
#include <stdio.h>
void show_message_1( const char *msg )
{
printf( "%s", msg );
}
test3.c
Code:
#include <stdio.h>
void show_message_2( const char *msg )
{
printf( "%s", msg );
}
This can be compiled with cc or gcc using: gcc -o testprog test1.c test2.c test3.c
Having said all that, let me point out that prototyping is (in my opinion) good documentation. As a programmer, you should understand the circumstances where prototyping is required. You should also include a prototype for every function, near the top of your source file, so a quick glance reveals what that module contains.