Header files y librerías en C

Programación retro del Commodore 64

  • Programación retro del Commodore 64
  • “Programación Retro del Commodore 64” es un blog sobre el hardware, el sistema operativo, y la programación del Commodore 64. Y más específicamente sobre programación en ensamblador. Pretende ser un blog con información de calidad, y referencia en español de la programación retro de esta maravillosa máquina.
    • Mi blog
« Publicado el: 25/08/2022 »

C es un lenguaje de programación procedimental, lo que quiere decir que una de las abstracciones principales que se usan a la hora de programar en C son los “procedimientos”, también llamados funciones o métodos, según el lenguaje. Yo creo que el término más común en el caso de C es el de “función”.

Una función viene a ser el equivalente en C de una rutina jsr – rts en ensamblador del 6502 / 6510. La principal diferencia es que las llamadas a funciones C admiten parámetros de entrada y salida, mientras que las llamadas a rutinas no admiten parámetros per sé, sino que hay que “simularlos” mediante el uso de posiciones de memoria o usando los registros del microprocesador.

Para poder usar una función de C, es decir, para poder llamarla, la función tiene que estar declarada previamente en el programa. Por ejemplo, si tenemos un programa así:

la compilación del programa fallará, ya sea con cc65 o con cualquier otro compilador de C, ya que la función factorial() primero se llama y luego se define (esto es incorrecto):

Sin embargo, si el programa lo redefinimos así:

ahora la compilación funcionará correctamente:

Es más, cuando decimos que la función llamada tiene que estar “declarada” previamente, no quiere decir que tenga que estar implementada con todo su código, sino que es suficiente con que el programador aporte el “prototipo”, que en el fondo es el nombre de la función y los parámetros de entrada y salida. Con esta información el compilador ya puede compilar, comprobando si la llamada a la función factorial() que se encuentra es sintácticamente correcta o no.

Aquí vemos el programa anterior retocado con un prototipo:

Pues bien, cuando un programa es grande y complejo, y cuando utiliza librerías estándar de C o suministradas por terceros, es habitual recoger los prototipos de las funciones que guardan relación entre sí, por ejemplo, por estar relacionadas con la entrada / salida o cualquier otra cuestión, en lo que se llama un “header file” (fichero de cabecera).

Un fichero de cabecera de C es un fichero con extensión *.h que incluye los prototipos de las funciones, y otras cosas como constantes, que se quieren compartir entre varios programas o ficheros. El fichero de cabecera se referencia luego desde los ficheros que van a usar esas funciones, utilizando para ello la instrucción #include <fichero-cabecera.h> del preprocesador de C. El preprocesador es un paso previo a la compilación.

Aquí vemos el programa retocado con un header file (aunque este programa es tan sencillo que no tiene mucho sentido hacerlo así, pero sirve de ejemplo):

En la siguiente entrada veremos los header files que aporta cc65 específicos para máquinas Commodore y el C64.

Código de ejemplo: factorial