Está en la página 1de 10

Fundamentos de Informática PRÁCTICA 9.

Otros aspectos de la programación en C

PRÁCTICA 9. Otros aspectos de la programación en C

9.1. Objetivos de la práctica.


El objetivo de esta práctica es mostrar algunos conceptos de la programación en
C que hasta ahora no han sido tratados en prácticas anteriores: ficheros de proyecto,
gestión completa de ficheros secuenciales, implementación de pilas, colas, listas, etc.

9.2. Ficheros de proyecto.


Cuando se crean grandes aplicaciones, es necesario estructurar los programas,
dividiéndolos en módulos. Cada módulo constará de un conjunto de funciones, tipos de
datos definidos por el usuario, constantes, variables, etc.; de manera que el objetivo del
módulo sea resolver un determinado subproblema dentro del problema global. Este
concepto es lo que se conoce como programación modular.
En C, habitualmente, cada uno de los módulos de una aplicación dará lugar a dos
ficheros. Ambos suelen tener igual nombre, pero varía su extensión y contenido. Uno de
ellos, con extensión “.H” (fichero de cabecera), contendrá la declaración de las
operaciones del módulo; mientras el otro, con extensión “.C” (fichero de
implementación), contendrá la implementación de esas operaciones.
En el fichero de cabecera suelen aparecer los prototipos de las funciones
implementadas por el módulo que se desea sean visibles fuera del mismo; así como los
tipos de datos definidos por el usuario, constantes y variables globales que queremos
que se puedan usar por otros módulos. Lo que nunca debe aparecer es código de alguna
función o cualquier otra cosa interna al módulo que estamos diseñando.
El fichero de implementación contendrá, como su nombre indica, la
implementación de las funciones necesarias para el diseño del módulo, es decir, el
código de dichas funciones. Además contendrá cualquier otra cosa que se considere
interna al módulo, y por tanto, únicamente visible dentro del mismo.
En C, la descomposición del código de un programa en varios módulos obliga a
la utilización de un fichero de proyecto.
Los ficheros de proyecto son ficheros especiales que no contienen código C, sino
una lista de los ficheros (módulos) que componen nuestro programa, permitiendo así la
programación modular en C. En un fichero de proyecto sólo aparecen los ficheros de
implementación (“.C”) necesarios para la construcción de nuestra aplicación. Como ya
sabemos, será dentro de los ficheros de implementación donde aparecerán las directivas
#include necesarias para incluir los ficheros de cabecera que necesite cada fichero de
implementación (como mínimo suele necesitar la inclusión de su fichero de cabecera
asociado).
Un fichero de proyecto posee la extensión “.PRJ”. El compilador observando el
fichero de proyecto sabrá cuántos módulos componen la aplicación, y por tanto, cuántos
ficheros deben ser compilados y enlazados para crear el programa ejecutable final.
Como todos los módulos deben ser enlazados para formar un único ejecutable, sólo uno

1/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

de ellos poseerá la función main. El nombre del fichero ejecutable sera el mismo del
fichero de proyecto, pero lógicamente con la extensión “.EXE”.
Es importante saber que los distintos módulos de la aplicación deben poder
compilarse de forma independiente. Es decir, como en C el proceso de compilación se
realiza completo antes de pasar al enlazado de los módulos, cada módulo debe
compilarse correctamente; aunque sólo tendrá sentido cuando las referencias a otros
módulos sean conocidas, lo cual ocurrirá después de que el enlazador cree el programa
final (“.EXE”).
El proceso de creación de un fichero de proyecto varía dependiendo del
compilador utilizado. Mostraremos aquí el proceso a seguir en el caso del compilador
Borland C++.
Para crear un fichero de proyecto dentro del compilador Borland C++ habrá que
seleccionar la opción “Project” dentro del menú principal. Al elegir esta opción se
desplegará otro menú. La opción “Open Project” permite crear un fichero de proyecto
o abrir uno ya existente. Al seleccionar esta opción aparece un cuadro de diálogo similar
al usado para abrir o guardar un fichero. Si se indica un nombre de fichero de proyecto
no existente éste se creará, en caso contrario se abrirá el fichero indicado.
En cualquier caso, tras seleccionar el fichero de proyecto se abrirá en pantalla
una ventana de proyecto. Dentro de la misma aparece el nombre de los ficheros de
implementación (“.C”) que componen el proyecto, así como otros datos asociados con
los mismos (número de líneas que poseen, su localización en el disco,...). Si la ventana
de proyecto no apareciera puede obtenerse mediante la opción “Project” perteneciente
al menú “Window”.
Para añadir nuevos ficheros de implementación a nuestro proyecto se utilizaría la
opción “Add item” perteneciente también al menú “Project”. Al seleccionar esta
opción aparecerá un cuadro de diálogo similar al usuado para abrir o guardar un fichero,
pudiendo seleccionar los ficheros de implementación que formarán parte de ese
proyecto. En este cuadro de diálogo, el botón “Add” permite añadir otro fichero de
implementación al proyecto, y el botón “Done” permite finalizar la introducción de los
ficheros de implementación.
A partir de este momento, la compilación, una vez abierto el proyecto,
conllevaría la compilación de todos los ficheros de implementación indicados, para
posteriormente enlazarlos formando el ejecutable final de nuestro programa. Para esta
compilación sólo es necesario que se encuentre abierto el fichero de proyecto. No es
necesario que los ficheros de implementación se encuentren abiertos en ventanas.
El menú “Project” presenta otras opciones de interés como: “Close project”
(cierra el proyecto actual), “Delete item” (elimina un fichero de implementación de
nuestro proyecto), “Include files” (muestra los ficheros de cabecera “.h” que se han
incluido en un fichero de implementación de nuestro proyecto), etc.

9.3. Ejemplo de gestión de un fichero secuencial en C.


/****************************************************************************/
/* Posible ejemplo de gestión de un fichero secuencial */
/****************************************************************************/

2/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

/*************************** Ficheros cabecera ******************************/

#include <conio.h> // Por getch() y clrscr()


#include <stdio.h>

/******************************* Constantes *********************************/

/* Valores de retorno posibles */


#define OK 0 /* Funcionamiento correcto */
#define ERRFICH -1 /* Error en la gestión del fichero */

/**************************** Tipos de datos ********************************/

/* Definimos el formato para los registros del fichero secuencial */


typedef struct {long int Dni;
char NomApe[31];
} TipoRegistro;

/**************************** Programa de prueba ****************************/

int main(void)
{
FILE * Fichero;
TipoRegistro Registro;
int i;

/* Controlar errores al crear el fichero Ejemplo.dat */


Fichero=fopen("Ejemplo.dat","wb");
if (Fichero == NULL)
{printf("\nError: Imposible crear el fichero Ejemplo.dat\n");
return(ERRFICH);
}

/* Leer datos de alumnos hasta que el DNI sea -1 */


i=1;
printf("Introduzca DNI del alumno 1 (-1 para salir): ");
scanf("%ld",&Registro.Dni);
while (Registro.Dni != -1)
{printf("Introduzca nombre y apellidos del alumno %d: ",i);
scanf("%s",Registro.NomApe);

/* Escribir el registro en el fichero, controlando errores */


if (fwrite(&Registro,sizeof(Registro),1,Fichero) != 1) break;

/* Leer datos siguiente alumno */


i++;
printf("\nIntroduzca DNI del alumno %d (-1 para salir): ",i);
scanf("%ld",&Registro.Dni);
}

/* Cerrar fichero */
fclose(Fichero);
printf("\n¡Fichero creado! Pulse una tecla para proceder a su lectura...");
getch();
clrscr(); // Borra la pantalla

/* Controlar errores al abrir el fichero Ejemplo.dat para lectura */


Fichero=fopen("Ejemplo.dat","rb");
if (Fichero == NULL)
{printf("\nError: Imposible abrir el fichero Ejemplo.dat\n");
return(ERRFICH);
}

/* Mostrar datos de los registros del fichero mientras no sea su fin */


i=1;
while (! feof(Fichero))
{/* Leer un registro del fichero, controlando errores */
if (fread(&Registro,sizeof(Registro),1,Fichero) != 1) break;

/* Mostrar datos por pantalla */


printf("DNI del alumno %d: %ld\n",i,Registro.Dni);
printf("Nombre y apellidos del alumno %d: %s\n\n",i,Registro.NomApe);

3/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

/* Siguiente alumno */
i++;
}

/* Cerrar fichero */
fclose(Fichero);
return(OK);
}

9.4. Ejemplo de implementación de una pila en C.


/****************************************************************************/
/* Posible implementación de una pila mediante un array en C */
/****************************************************************************/

/*************************** Ficheros cabecera ******************************/

#include <conio.h>
#include <stdio.h>

/******************************* Constantes *********************************/

/* Valores booleanos a utilizar */


#define NO 0
#define SI !NO

/* La pila tendrá un máximo de MAXPILA posiciones */


#define MAXPILA 100

/******************************* Tipos de datos *****************************/

/* Definimos el tipo para los elementos de la pila, así como un nueva


estructura de datos con el formato de la pila.
La definición de la pila es estática, por lo que sólo necesitamos un
array y un puntero a la cima de la pila */
typedef char TipoElem; // Aquí se cambiaría fácilmente el tipo de los elementos
typedef struct {TipoElem Contenido[MAXPILA];
int PuntCima;
} TipoPila;

/* Si tuvieramos que definir alguna variable del tipo pila sería:

TipoPila Pila;

*/

/******************************** Prototipos ********************************/

void IniciarPila(TipoPila * Pila);


void InsertarPila(TipoPila * Pila,TipoElem Elemento);
TipoElem SacarPila(TipoPila * Pila);
int VaciaPila(TipoPila Pila);
int LlenaPila(TipoPila Pila);

/********************************* Funciones ********************************/

/* Inicia la pila, indicando que no contiene elementos */


void IniciarPila(TipoPila * Pila)
{
Pila->PuntCima=-1;
}

/* Inserta un nuevo elemento en la cima de la pila */


void InsertarPila(TipoPila * Pila,TipoElem Elemento)
{
Pila->PuntCima++;
Pila->Contenido[Pila->PuntCima]=Elemento;
}

4/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

/* Saca el elemento que se encuentra en la cima de la pila */


TipoElem SacarPila(TipoPila * Pila)
{
TipoElem Elemento;

Elemento=Pila->Contenido[Pila->PuntCima];
Pila->PuntCima--;
return(Elemento);
}

/* Indica si la pila se encuentra vacía, debe invocarse antes de sacar un


elemento de la pila */
VaciaPila(TipoPila Pila)
{
if (Pila.PuntCima == -1) return(SI);
return(NO);
}

/* Indica si la pila se encuentra llena, debe invocarse antes de insertar un


elemento en la pila */
LlenaPila(TipoPila Pila)
{
if (Pila.PuntCima == MAXPILA-1) return(SI);
return(NO);
}

/**************************** Programa de prueba ****************************/

/* Ejemplo de utilización de la pila. Se suelen utilizar cuando debe


almacenarse cierta información y obtenerla en orden inverso */
void main(void)
{
TipoPila PilaEjemplo;
TipoElem ElemEjemplo;

IniciarPila(&PilaEjemplo);
printf("Introduzca los caracteres en la pila ('.' para finalizar):\n");
ElemEjemplo=getch();
// La inserción de elementos finaliza al introducir un “.” o llenarse la pila
while ((ElemEjemplo != '.') && (! LlenaPila(PilaEjemplo)))
{
InsertarPila(&PilaEjemplo,ElemEjemplo);
putch(ElemEjemplo); // Escribir el carácter, se ha insertado en la pila
ElemEjemplo=getch();
}

printf("\n\rPila:\n");
while (! VaciaPila(PilaEjemplo))
{
ElemEjemplo=SacarPila(&PilaEjemplo);
putch(ElemEjemplo);
}
}

9.5. Ejemplo de implementación de una cola (circular) en C.


/****************************************************************************/
/* Posible implementación de una cola (circular) mediante un array en C */
/****************************************************************************/

/*************************** Ficheros cabecera ******************************/

#include <conio.h>
#include <stdio.h>

/******************************* Constantes *********************************/

/* Valores booleanos a utilizar */


#define NO 0
#define SI !NO

5/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

/* La cola tendrá un máximo de MAXCOLA posiciones */


#define MAXCOLA 100

/**************************** Tipos de datos ********************************/

/* Definimos el tipo para los elementos de la cola, así como una nueva
estructura de datos con el formato de la cola.
La definición de la cola es estática, por lo que sólo necesitamos un
array y un puntero a la cabeza y otro al final de la cola */
typedef char TipoElem; // Aquí se cambiaría fácilmente el tipo de los elementos
typedef struct {TipoElem Contenido[MAXCOLA];
int PuntCabeza;
int PuntFinal;
} TipoCola;

/* Si tuvieramos que definir alguna variable del tipo cola sería:

TipoCola Cola;

*/

/******************************** Prototipos ********************************/

void IniciarCola(TipoCola * Cola);


void InsertarCola(TipoCola * Cola,TipoElem Elemento);
TipoElem SacarCola(TipoCola * Cola);
int VaciaCola(TipoCola Cola);
int LlenaCola(TipoCola Cola);

/********************************* Funciones ********************************/

/* Inicia la cola, indicando que no contiene elementos. Ambos punteros


apuntan a la última posición de la cola para que al incrementarlos pasen
a la primera */
void IniciarCola(TipoCola * Cola)
{
Cola->PuntCabeza=Cola->PuntFinal=MAXCOLA-1;
}

/* Inserta un nuevo elemento al final de la cola */


void InsertarCola(TipoCola * Cola,TipoElem Elemento)
{
if (Cola->PuntFinal == MAXCOLA-1) Cola->PuntFinal=0;
else Cola->PuntFinal++;
Cola->Contenido[Cola->PuntFinal]=Elemento;
}

/* Saca el elemento que se encuentra en la cabeza de la cola */


TipoElem SacarCola(TipoCola * Cola)
{
if (Cola->PuntCabeza == MAXCOLA-1) Cola->PuntCabeza=0;
else Cola->PuntCabeza++;
return(Cola->Contenido[Cola->PuntCabeza]);
}

/* Indica si la cola se encuentra vacía, debe invocarse antes de sacar un


elemento de la cola */
VaciaCola(TipoCola Cola)
{
if (Cola.PuntCabeza == Cola.PuntFinal) return(SI);
return(NO);
}

/* Indica si la cola se encuentra llena, debe invocarse antes de insertar un


elemento en la cola */
LlenaCola(TipoCola Cola)
{
int FinalSig;

if (Cola.PuntFinal == MAXCOLA-1) FinalSig=0;

6/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

else FinalSig=Cola.PuntFinal+1;
if (FinalSig == Cola.PuntCabeza) return(SI);
return(NO);
}

/**************************** Programa de prueba ****************************/

/* Ejemplo de utilización de la cola. Se suelen utilizar cuando debe


almacenarse cierta información y obtenerla en el mismo orden. También es
muy útil para indicar de quién es el turno (de imprimir en una impresora,
usar el procesador,...) */
void main(void)
{
TipoCola ColaEjemplo;
TipoElem ElemEjemplo;

IniciarCola(&ColaEjemplo);
printf("Introduzca los caracteres en la cola ('.' para finalizar):\n");
ElemEjemplo=getch();
// La inserción de elementos finaliza al introducir un “.” o llenarse la cola
while ((ElemEjemplo != '.') && (! LlenaCola(ColaEjemplo)))
{
InsertarCola(&ColaEjemplo,ElemEjemplo);
putch(ElemEjemplo); // Escribir el carácter, se ha insertado en la cola
ElemEjemplo=getch();
}

printf("\n\rCola:\n");
while (! VaciaCola(ColaEjemplo))
{
ElemEjemplo=SacarCola(&ColaEjemplo);
putch(ElemEjemplo);
}
}

9.6. Ejemplo de implementación de una lista en C.


/****************************************************************************/
/* Posible implementación de una lista con encadenamiento simple en C */
/****************************************************************************/

/*************************** Ficheros cabecera ******************************/

#include <alloc.h>
#include <conio.h>
#include <stdio.h>

/******************************* Constantes *********************************/

/* Valores booleanos a utilizar */


#define NO 0
#define SI !NO

/* Constantes usadas para indicar el resultado de la inserción en la lista */


#define OK 0 /* La inserción se realizó correctamente */
#define EXISTE 1 /* La inserción no se realizó por ya existir el elemento */
#define NOMEM 2 /* La inserción no se realizó por falta de memoria */

/* Constantes usadas para indicar el resultado de la eliminación en la lista */


#define OK 0 /* La eliminación se realizó correctamente */
#define NOEXISTE 1 /* La eliminación no se realizó por no existir el elemento */
#define VACIA 2 /* La eliminación no se realizó por estar la lista vacía */

/**************************** Tipos de datos ********************************/

/* Definimos el tipo para la información que almacenará cada nodo de la lista,


también definimos la estructura de cada nodo y la de la lista completa.
La estructura de la lista está formada por un solo campo, el puntero a la
cabeza de la lista */
typedef char TipoElem; // Aquí se cambiaría fácilmente el tipo de los elementos
typedef struct Nodo {TipoElem Contenido;
struct Nodo * PuntSig;
} TipoNodo;

7/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

typedef struct {
TipoNodo * PuntCabeza;
} TipoLista;

/* Si tuviéramos que definir alguna variable de tipo lista sería:

TipoLista Lista;

*/

/******************************** Prototipos ********************************/

void IniciarLista(TipoLista * Lista);


void ReiniciarLista(TipoLista * Lista);
TipoNodo * BuscarLista(TipoLista Lista,TipoElem Elemento);
int InsertarLista(TipoLista * Lista,TipoElem Elemento);
int SacarLista(TipoLista * Lista,TipoElem Elemento);
int VaciaLista(TipoLista Lista);
void VerLista(TipoLista Lista);

/********************************* Funciones ********************************/

/* Inicia la lista, indicando que no contiene elementos */


void IniciarLista(TipoLista * Lista)
{
Lista->PuntCabeza=NULL;
}

/* Reinicia la lista, eliminando todos los elementos que pueda poseer


actualmente */
void ReiniciarLista(TipoLista * Lista)
{
TipoNodo * Puntero;

while (Lista->PuntCabeza != NULL)


{Puntero=Lista->PuntCabeza;
Lista->PuntCabeza=Lista->PuntCabeza->PuntSig;
free(Puntero);
}
}

/* Busca dentro de la lista hasta encontrar un nodo con contenido mayor o


igual al de Elemento (ordenación ascendente de los elementos de la lista).
Retorna el puntero al nodo anterior si lo encuentra. Casos especiales:
- Si Elemento es menor que el primer elemento de la lista retorna un
puntero igual a NULL.
- Si la lista está vacía retornaría un puntero a NULL, por lo que no
conviene invocar a esta función con la lista vacía, ya que no podría
distinguirse entre este caso y el anterior.
- Si ningún nodo de la lista tiene un contenido mayor o igual a Elemento
retorna un puntero al último nodo de la lista */
TipoNodo * BuscarLista(TipoLista Lista,TipoElem Elemento)
{
TipoNodo * PuntAnt,* PuntAct;

PuntAnt=NULL;
PuntAct=Lista.PuntCabeza;
while (PuntAct != NULL)
if (PuntAct->Contenido < Elemento)
{PuntAnt=PuntAct;
PuntAct=PuntAct->PuntSig;
}
else PuntAct=NULL;
return(PuntAnt);
}

/* Inserta un nuevo elemento en la lista teniendo en cuenta una ordenación


ascendente. Retorna:
- OK: La inserción se realizó correctamente.
- EXISTE: La inserción no se realizó por ya existir el elemento.

8/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

- NOMEM: La inserción no se realizó por falta de memoria */


InsertarLista(TipoLista * Lista,TipoElem Elemento)
{
TipoNodo * PuntAnt,* PuntElem;

if (VaciaLista(*Lista)) /* Inserción en lista vacía */


{Lista->PuntCabeza=(TipoNodo *) malloc(sizeof(TipoNodo));
if (Lista->PuntCabeza == NULL) return(NOMEM); /* Sin memoria */
Lista->PuntCabeza->Contenido=Elemento;
Lista->PuntCabeza->PuntSig=NULL;
}
else
if (Elemento < Lista->PuntCabeza->Contenido) /* Elemento menor que el 1º */
{/* Inserción en la primera posición de la lista */
PuntElem=(TipoNodo *) malloc(sizeof(TipoNodo));
if (PuntElem == NULL) return(NOMEM); /* Sin memoria */
PuntElem->Contenido=Elemento;
PuntElem->PuntSig=Lista->PuntCabeza;
Lista->PuntCabeza=PuntElem;
}
else
if (Elemento == Lista->PuntCabeza->Contenido) return(EXISTE); /* Existe */
else
{PuntAnt=BuscarLista(*Lista,Elemento);
if (PuntAnt->PuntSig == NULL) /* Elemento es el mayor de la lista */
{/* Inserción en la última posición de la lista */
PuntElem=(TipoNodo *) malloc(sizeof(TipoNodo));
if (PuntElem == NULL) return(NOMEM); /* Sin memoria */
PuntElem->Contenido=Elemento;
PuntElem->PuntSig=NULL;
PuntAnt->PuntSig=PuntElem;
}
else
if (Elemento == PuntAnt->PuntSig->Contenido) return(EXISTE); /* Existe */
else
{/* Inserción en el medio de la lista */
PuntElem=(TipoNodo *) malloc(sizeof(TipoNodo));
if (PuntElem == NULL) return(NOMEM); /* Sin memoria */
PuntElem->Contenido=Elemento;
PuntElem->PuntSig=PuntAnt->PuntSig;
PuntAnt->PuntSig=PuntElem;
}
}
return(OK); /* Inserción correcta */
}

/* Saca de la lista el nodo cuyo contenido coincide con el de Elemento.


Retorna:
- OK: La eliminación se realizó correctamente.
- NOEXISTE: La eliminación no se realizó por no existir el elemento.
- VACIA: La eliminación no se realizó por estar la lista vacía */
SacarLista(TipoLista * Lista,TipoElem Elemento)
{
TipoNodo * PuntAnt,* PuntElem;

if (VaciaLista(*Lista)) return(VACIA); /* Eliminación en lista vacía */


else
if (Elemento < Lista->PuntCabeza->Contenido) return(NOEXISTE); /* Menor que el 1º */
else
if (Elemento == Lista->PuntCabeza->Contenido) /* Eliminar primer nodo */
{
PuntElem=Lista->PuntCabeza;
Lista->PuntCabeza=Lista->PuntCabeza->PuntSig;
free(PuntElem);
}
else
{PuntAnt=BuscarLista(*Lista,Elemento);
if (PuntAnt->PuntSig == NULL) return(NOEXISTE); /* Elemento no existe */
else
if (Elemento == PuntAnt->PuntSig->Contenido)
{/* Eliminar nodo en medio o último de la lista */
PuntElem=PuntAnt->PuntSig;
PuntAnt->PuntSig=PuntAnt->PuntSig->PuntSig;

9/10
Fundamentos de Informática PRÁCTICA 9. Otros aspectos de la programación en C

free(PuntElem);
}
else return(NOEXISTE); /* Elemento no existe */
}
return(OK); /* Eliminación correcta */
}

/* Indica si la lista se encuentra vacía, debe invocarse antes de sacar un


elemento de la lista */
VaciaLista(TipoLista Lista)
{
if (Lista.PuntCabeza == NULL) return(SI);
return(NO);
}

/* Recorre toda la lista, imprimiendo el valor de cada elemento */


void VerLista(TipoLista Lista)
{
TipoNodo * Puntero;

Puntero=Lista.PuntCabeza;
while (Puntero != NULL)
{/* Escribir el contenido de cada elemento de la lista, en este caso "putch()"
al ser sólo un carácter */
putch(Puntero->Contenido);
Puntero=Puntero->PuntSig;
}
}

/**************************** Programa de prueba ****************************/

/* Ejemplo de utilización de una lista. Se suelen utilizar cuando NO se


conoce a priori la cantidad de memoria necesaria para almacenar la
información y por tanto se utiliza memoria dinámica */
void main(void)
{
TipoLista ListaEjemplo;
TipoElem ElemEjemplo;
int Retorno;

IniciarLista(&ListaEjemplo);
printf("Introduzca los caracteres en la lista ('.' para finalizar):\n");
Retorno=OK;
ElemEjemplo=getch();
// La inserción de elementos finaliza al introducir un “.” o acabarse la memoria
while ((ElemEjemplo != '.') && (Retorno != NOMEM))
{
Retorno=InsertarLista(&ListaEjemplo,ElemEjemplo);
if (Retorno == OK) putch(ElemEjemplo); // Escribir el carácter, insertado en la lista
if (Retorno != NOMEM) ElemEjemplo=getch();
}

putch(13); // Salto de línea (código ASCII 13 = RETURN) para mostrar la lista introducida
VerLista(ListaEjemplo);

putch('\r'); // Salto de línea para empezar a eliminar elementos de la lista


Retorno=OK;
ElemEjemplo=getch();
// La eliminación de elementos finaliza al introducir un “.” o vaciarse la lista
while ((ElemEjemplo != '.') && (Retorno != VACIA))
{
Retorno=SacarLista(&ListaEjemplo,ElemEjemplo);
if (Retorno == OK) putch(ElemEjemplo); // Escribir el carácter, eliminado de la lista
if (Retorno != VACIA) ElemEjemplo=getch();
}

putch(13); // Salto de línea para mostrar la lista final


VerLista(ListaEjemplo);
ReiniciarLista(&ListaEjemplo); /* Liberar el espacio ocupado por la lista */
}

10/10

También podría gustarte