Los programas sencillos, como los ejemplo planteados hasta ahora, normalmente no necesitan un nivel de estructuraci�n elevado. Pero cuando �stos crecen un poco necesitamos estructurarlos adecuadamente para mantenerlos legibles, facilitar su mantenimiento y para poder reutilizar ciertas porciones de c�digo. El mecanismo de C que nos permite esto son las funciones. Con los compiladores, los fabricantes nos proporcionan un conjunto importante de funciones de librer�a. A veces, nos puede interesar construir nuestras propias librer�as. Ya hemos utilizado funciones, pero veamos c�mo debemos definirlas.
Los prototipos de funciones son una caracter�stica clave de la recomendaci�n ANSI del C. Un prototipo es una declaraci�n que toma la forma:
tipo_resultado nombre_funci�n ( tipo_par�metro nombre_par�metro ... );
- int fact_i ( int v );
- int mayor ( int a, int b );
- int cero ( double a );
- long raiz ( long valor );
- void final_countdown ( void );
- int main ( int argc, char **argv );
Observando el prototipo de una funci�n podemos decir exactamente que tipo de par�metros necesita y que resultado devuelve. Si una funci�n tiene como argumento void, quiere decir que no tiene argumentos, al igual que si el resultado es void, no devuelve ning�n valor.
En la vieja definici�n de Kernighan y Ritchie el tipo que devolv�a una funci�n se declaraba �nicamente si era distinto de int. Similarmente, los par�metros eran declarados en el cuerpo de la funci�n, en lugar de utilizar la lista de par�metros. Por ejemplo:
mayor ( a, b ) int a; int b; { ... }
Las funciones al viejo estilo se compilan correctamente en muchos compiladores actuales. Por contra, proporcionan menos informaci�n sobre sus par�metros y errores que afecten al tipo de par�metros de llamada a las funciones no pueden ser detectados autom�ticamente. Por tanto, la declaraci�n de una funci�n debe escribirse igual que su prototipo pero sin el punto y coma final. El cuerpo de la funci�n le sigue encerrado entre llaves.
En un programa que est� formado por distintas partes bien diferenciadas es conveniente utilizar m�ltiples ficheros fuente. Cada fuente agrupa las funciones semejantes, como por ejemplo en un compilador podr�amos tener un fuente para el an�lisis l�xico, otro para el sint�ctico y otro para la generaci�n de c�digo. Pero en un fuente necesitaremos funciones que se han definido en otro. Para ello, escribiremos, un fichero de cabecera (header), que contendr� las declaraciones que podemos necesitar en otros fuente. As�, en el fuente que implementa el analizador sint�ctico pondremos una l�nea #include "lexic.h". De esta forma al compilar el m�dulo sint�ctico tendremos todos los prototipos de las funciones del l�xico y el compilador podr� detectar malas utilizaciones de las funciones all� definidas.