67 - Aplicaciones en C con más de un archivo fuente (proyectos con múltiples archivos)


Ver video

En programas medianos o grandes es inviable disponer todo el código fuente en un único archivo. Yendo a un ejemplo extremo el sistema operativo Linux esta compuesto por más de 50000 archivos.

En este concepto veremos como implementar una aplicación que tenga dos archivos *.c y que luego se compilen y generen un único archivo ejecutable.

Utilizando Code::Blocks nos facilitará esta actividad mediante la creación de un proyecto.

Problema 1:

Se tiene la siguiente declaración:

typedef struct {
    int codigo;
    char descripcion[41];
    float precio;
} tproducto; 

Definir un vector de 4 elementos de tipo tproducto.

Implementar una aplicación que muestre un menú de opciones que permita:

  1. Carga del vector.
  2. Impresión del vector.
  3. Finalizar

Como dijimos resolveremos este problema disponiendo los algoritmos de carga e impresión del vector en un archivo y en otro archivo el menú de opciones.

Para crear un proyecto en Code::Blocks elegimos la opción creación proyecto Code::Blocks

Aparece un diálogo donde elegiremos la opción "Empty Project" (proyecto vacío):

creación proyecto Code::Blocks

Aparecerán una serie de diálogos para configurar el proyecto:

creación proyecto Code::Blocks

Uno de los pasos importantes es indicar el nombre del proyecto y la carpeta donde se debe almacenar el proyecto:

creación proyecto Code::Blocks

En el diálogo siguiente dejamos por defecto los datos propuestos:

creación proyecto Code::Blocks

Ya tenemos creado el proyecto y del lado izquierdo en el Workspace podemos verlo:

creación proyecto Code::Blocks

Ahora tenemos que crear los dos archivos con extensión C que tendrán los algoritmos propiamente dicho.
Crearemos dos archivo llamados "main.c" que será el principal que contendrá la función main y otro archivo llamado "productos.c" que tendrá los algoritmos para poder cargar e imprimir el vector.

Estando seleccionado el proyecto001 elegimos desde el menú de opciones File -> Empty file

creación proyecto Code::Blocks

Aparece un diálogo para confirmar si el archivo lo queremos agregar al proyecto seleccionado:

creación proyecto Code::Blocks

Indicamos seguidamente el nombre del archivo a crear, en nuestro caso lo llamamos "main.c":

creación proyecto Code::Blocks

Después de esto ya tenemos agregado a nuestro proyecto el archivo "main.c":

creación proyecto Code::Blocks

Efectuamos los mismos pasos para agregar el segundo archivo "productos.c":

creación proyecto Code::Blocks

Ahora crearemos un tercer archivo llamado "productos.h", tener en cuenta que la extensión es h (header) los pasos son los mismos hechos anteriormente (luego veremos cual es el objetivo de este tercer archivo)

Luego de crearlo nuestro proyecto tiene esta estructura:

creación proyecto Code::Blocks

Como vemos los archivos con extensión *.h se agrupan en otra parte de nuestro proyecto, tenemos una sección con todos los archivos *.c y otra con todos los archivos *.h

Primero codificaremos el archivo productos.h

En este tipo de archivos declaramos tipos de datos, macros, enumeraciones, uniones, prototipos de funciones etc. que sean de uso común a varios archivos de nuestro programa.

Archivo: productos.h

typedef struct {
    int codigo;
    char descripcion[41];
    float precio;
} tproducto;

#define CANT 4

void cargar(tproducto productos[CANT]);
void imprimir(tproducto productos[CANT]);

En este archivo declaramos el tipo de dato tproducto y la macro CANT.

Además declaramos los prototipos de las funciones que se implementarán en el archivo productos.c. Los prototipos son las cabeceras de las funciones.

Archivo: main.c

#include<stdio.h>

#include"productos.h"


int main()
{
    tproducto productos[CANT];
    int opcion;
    do {
        printf("1-Carga de productos.\n");
        printf("2-Listado de productos.\n");
        printf("3-Finalizar programa..\n\n");
        printf("Elija su opcion:");
        scanf("%i",&opcion);
        switch (opcion) {
            case 1:cargar(productos);
                   break;
            case 2:imprimir(productos);
                   break;
        }
    } while(opcion!=3);

    return 0;
}

En la función main definimos un vector de tipo tproducto:

int main()
{
    tproducto productos[CANT];

¿Cómo podemos definir una variable de un tipo de dato que no está definido en el archivo?

La respuesta está en que hemos incluido el archivo que contiene dicha declaración del tipo de dato:

#include"productos.h"

La sintaxis para incluir archivos .h creados por nosotros y contenidos en el proyecto es encerrarlos entre comillas dobles y no con los caracteres <>

El tercer archivo "productos.c" tiene por objetivo cargar e imprimir el vector..

Archivo: productos.c

#include<stdio.h>
#include"productos.h"

void cargar(tproducto productos[CANT])
{
    int f;
    for(f=0;f<CANT;f++)
    {
        printf("Ingrese el codigo:");
        scanf("%i",&productos[f].codigo);
        fflush(stdin);
        printf("Ingrese la descripcion:");
        gets(productos[f].descripcion);
        printf("Ingrese el precio:");
        scanf("%f",&productos[f].precio);
    }
}

void imprimir(tproducto productos[CANT])
{
    int f;
    for(f=0;f<CANT;f++)
    {
        printf("Codigo:%i\n",productos[f].codigo);
        printf("Descripcion:%s\n",productos[f].descripcion);
        printf("Precio:%0.2f\n",productos[f].precio);
    }
    printf("\n\n");
}

En este archivo también trabajamos con el tipo de dato "tproducto" y la macro CANT por lo que primero hacemos la inclusión del archivo "productos.h":

#include"productos.h"

También incluimos el archivo "stdio.h" ya que en ese archivo se declara el prototipo de la función printf y scanf:

#include<stdio.h>

Los algoritmos propiamente dichos para la carga e impresión del vector no varían a como los vimos cuando trabajamos con un único archivo.

Cuando ejecutamos este proyecto se genera un único archivo *.exe que resulta de la compilación de los archivos main.c, productos.c, productos.h y demás librerías propias del lenguaje C.

El resultado de ejecutar el programa mostrará en la consola una interfaz similar a esta:

creación y ejecución de proyecto Code::Blocks

Retornar