Si se adopta el modelo modular entonces se querrá tener para cada módulo las definiciones de las variables, los prototipos de las funciones, etc. Sin embargo, ¿qué sucede si varios módulos necesitan compartir tales definiciones? En tal caso, lo mejor es centralizar las definiciones en un archivo, y compartir el archivo entre los módulos. Tal archivo es usualmente llamado un archivo cabecera. Ver video
Por convención estos archivos tienen el sufijo .h
Archivos cabecera de la biblioteca estándar, por ejemplo:
#include <stdio.h>
Se pueden definir los propios archivos cabecera y se pueden incluir en el programa como se muestra enseguida:
#include "mi_cabecera.h"
Los archivos cabecera por lo general sólo contienen definiciones de tipos de datos, prototipos de funciones y comandos del preprocesador de C.
Considerar el siguiente programa de ejemplo:
main.c
/*
* main.c
*/
#include "cabecera.h"
#include <stdio.h>
char *Otra_cadena = "Hola a Todos";
main()
{
printf("Ejecutando...\n");
/*
* Llamar a EscribirMiCadena() - definida en otro archivo
*/
EscribirMiCadena(MI_CADENA);
printf("Terminado.\n");
}
EscribirMiCadena.c
/*
* EscribirMiCadena.c
*/
extern char *Otra_cadena;
void EscribirMiCadena(EstaCadena)
char *EstaCadena;
{
printf("%s\n", EstaCadena);
printf("Variable Global = %s\n", Otra_cadena);
}
cabecera.h
/*
* cabecera.h
*/
#define MI_CADENA "Hola Mundo"
void EscribirMiCadena();
Cada módulo será compilado separadamente.
Algunos módulos tienen la directiva de preprocesamiento #include "cabecera.h" ya que comparten definiciones comunes. Algunos como main.c también incluyen archivos cabecera estándar. La función main.c llama a la función EscribirMiCadena() la cual esta en el módulo (archivo) EscribirMiCadena.c
El prototipo void de la función EscribirMiCadena esta definida en cabecera.h.
Observar que en general se debe decidir entre tener un módulo .c que tenga acceso solamente a la información que necesita para su trabajo, con la consecuencia de mantener muchos archivos cabecera y tener programas de tamaño moderado con uno o dos archivos cabecera (probablemente lo mejor) que compartan más definiciones de módulos.
Un problema que se tiene al emplear módulos es el compartir variables. Si se tienen variables globales declaradas y son instanciadas en un módulo, ¿cómo pueden ser pasadas a otros módulos para que sean conocidas?
Se podrían pasar los valores como parámetros a las funciones, pero:
puede ser esto laborioso si se pasan los mismos parámetros a muchas funciones o si la lista de argumentos es muy larga.
arreglos y estructuras muy grandes son difíciles de guardar localmente -- problemas de memoria con el stack.