Tabla de contenidos
En la actualidad existen múltiples lenguajes de programación denominados de “alto nivel”, es decir, aquellos que permiten escribir programas en un formato lejano al lenguaje máquina o ensamblador que es el que utiliza el procesador para ejecutar todos los programas. Java es un lenguaje de alto nivel “orientado a objeto” pues los programas se estructuran alrededor de clases y objetos. C, en cambio, no dispone de objetos y se estructura en base a un conjunto de funciones, por lo que se denomina un “lenguaje procedimental”.
Java es un lenguaje con una funcionalidad muy extensa, y aunque coincide con C en un porcentaje amplio de esta funcionalidad las diferencias entre ambos son mucho mayores que las coincidencias. Las construcciones del lenguaje C son mucho más simples que las de Java. En mecanismos tales como bucles, condicionales, etc., ambos lenguajes coinciden, pero en el resto de aspectos tales como la definición de estructuras de datos C ofrece mecanismos más simples.
Un programa en C es un conjunto de funciones, definiciones de
tipos de datos y declaraciones de variables contenidos en un conjunto de
ficheros. Un programa en C siempre comienza a ejecutar por la función con
nombre main
. Cualquier función puede llamar a cualquier función,
y las variables declaradas fuera de las funciones tienen ámbito global o local
al fichero que las contiene (si se declaran con el prefijo
static
). La siguiente figura ilustra la estructura de un programa
en C contenido en varios ficheros.
El compilador es el programa encargado de traducir un conjunto de funciones, definiciones y declaraciones en múltiples ficheros a un fichero ejecutable. El compilador de C tiene un comportamiento sorprendentemente sencillo y realiza mucho menos trabajo del que se está acostumbrado con otros compiladores como el de Java. Para crear un ejecutable, el compilador procesa los ficheros de código uno a uno de forma independiente, de forma que las definiciones de variables y funciones de un fichero no las recuerda cuando procesa el fichero siguiente. Además, el compilador realiza una única pasada por el texto, por lo que cuando se traduce un fichero, en un punto concreto del texto, sólo se dispone de las definiciones que se han encontrado hasta ese punto.
Como consecuencia de este comportamiento, una variable no
puede ser utilizada, a no ser que se haya declarado previamente en ese mismo
fichero. Igualmente, una función no puede ser invocada a no ser que se haya
incluido previamente en el mismo fichero. Para poder dividir igualmente el
código en múltiples ficheros el lenguaje permite la definición de
“prototipos de funciones” (el tipo del resultado que devuelven,
seguido del nombre de la función y del tipo de sus parámetros entre
paréntesis) sin incluir el código, y además permite la definición de variables
como “externas”, es decir, que están en otro fichero. A
continuación se muestran dos ficheros en los que la función
fill_in
y la variable table
están definidas en un
fichero pero las utiliza la función main
en el otro
fichero.
Fichero1.c
|
Fichero2.c
| ||||
---|---|---|---|---|---|
|
|
La línea 3 en Fichero2.c
notifica al
compilador que existe una tabla de 100 enteros con nombre table
definida en otro fichero. La línea 6 es un prototipo de función. Contiene el
tipo del resultado (void
) seguido del nombre de la función
(fill_in
) y de los nombres y tipos de los parámetros entre
paréntesis (int *t, int size
). Esta línea informa al compilador
que una función de estas características está definida en otro lugar de del
programa. Gracias a estas definiciones la línea 11 es correcta. La función
fill_in
puede ser invocada, y la variable table
es
conocida.
La línea 1 de ambos ficheros (#define
) es una directiva del preprocesador,
que indica que tiene que cambiar todas las ocurrencias de una cadena de caracteres dada (en
este caso SIZE
) por un valor específico (en este caso, 100
).
El preprocesador corre automáticamente antes que el compilador y se encarga de estas sustituciones.
Usa la directiva #define
siempre que vayas a definir constantes en tu programa,
sobre todo para los tamaños de arrays, y escribe siempre esas constantes en mayúsculas,
de forma que sean fáciles de leer y modificar.
Responde a las siguientes preguntas para ver si has entendido lo que se explica en este documento: