15
Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12] 1 ANSIC: Cabecera y Archivo Fuente Introducción: Últimamente he realizado aplicaciones pequeñas que pensé no necesitaba separar en módulos, lo curioso fue que estaba equivocado, tanto aplicaciones pequeñas como grandes requieren de la separación de módulos independientes para poder reutilizar el código entre otras ventajas que explicare más delante. Razón por la cual decidí realizar este post con el objetivo de aprender y espero sea de utilidad para otras personas. Para comenzar debemos aclarar que los lenguajes de programación actuales nos permiten el desarrollo de aplicaciones modulares, para permitir la reutilización de código y evitar rediseñar segmentos independientes que fueron creados en proyectos anteriores. Por esta razón los programadores pueden separar un programa en componentes más pequeños, en “C” se llaman módulos o subrutinas y en “C++” clases. Estos subprogramas permiten reutilizar y distribuir el código creado anteriormente. Las ventajas que ofrece al segmentar un programa son las siguientes: Si un equipo está desarrollando el programa, cada integrante puede desarrollar un módulo y al final integrar todo el proyecto. Mejor organización, ya que puedes agrupar funciones relacionadas en un mismo modulo, estilo orientado a objetos. La reutilización de los módulos en proyectos nuevos, reduciendo el tiempo de desarrollo. Cuando se realiza un cambio en algún modulo solo ese modulo es recompilado nuevamente y no todo el programa. Cabecera: Los archivos de cabecera (“header” en ingles) son archivos con extensión “*.h” y tienen el objetivo de declarar la interface del modulo y no el como esta implementado. En la interface solo se debe poner código que deseamos sea utilizado por otros módulos y no aquel código que sea de uso interno para el modulo. Los archivos de cabecera están formados por dos partes en general. 1. La primera parte es el protector de cabecera, el cual se utiliza para evitar que el mismo código de la cabecera se repita si esta misma cabecera es incluida en algún otro archivo fuente. Para poner el protector se utilizan el siguiente código del preprocesador: #ifndef NOMBRECABECERA_H #define NOMBRECABECERA_H // Interface o contenido de cabecera #endif

ANSI C: Cabecera y Archivo Fuente

Embed Size (px)

DESCRIPTION

Los lenguajes de programación actuales nos permiten el desarrollo de aplicaciones modulares, para permitir la reutilización de código y evitar rediseñar segmentos independientes que fueron creados en proyectos anteriores.

Citation preview

Page 1: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

1

ANSIC: Cabecera y Archivo Fuente

Introducción: Últimamente he realizado aplicaciones pequeñas que pensé no necesitaba separar en módulos, lo curioso fue que

estaba equivocado, tanto aplicaciones pequeñas como grandes requieren de la separación de módulos independientes

para poder reutilizar el código entre otras ventajas que explicare más delante. Razón por la cual decidí realizar este post

con el objetivo de aprender y espero sea de utilidad para otras personas.

Para comenzar debemos aclarar que los lenguajes de programación actuales nos permiten el desarrollo de

aplicaciones modulares, para permitir la reutilización de código y evitar rediseñar segmentos independientes que fueron

creados en proyectos anteriores.

Por esta razón los programadores pueden separar un programa en componentes más pequeños, en “C” se

llaman módulos o subrutinas y en “C++” clases. Estos subprogramas permiten reutilizar y distribuir el código creado

anteriormente.

Las ventajas que ofrece al segmentar un programa son las siguientes:

Si un equipo está desarrollando el programa, cada integrante puede desarrollar un módulo y al final integrar

todo el proyecto.

Mejor organización, ya que puedes agrupar funciones relacionadas en un mismo modulo, estilo orientado a

objetos.

La reutilización de los módulos en proyectos nuevos, reduciendo el tiempo de desarrollo.

Cuando se realiza un cambio en algún modulo solo ese modulo es recompilado nuevamente y no todo el

programa.

Cabecera: Los archivos de cabecera (“header” en ingles) son archivos con extensión “*.h” y tienen el objetivo de declarar la

interface del modulo y no el como esta implementado. En la interface solo se debe poner código que deseamos sea

utilizado por otros módulos y no aquel código que sea de uso interno para el modulo.

Los archivos de cabecera están formados por dos partes en general.

1. La primera parte es el protector de cabecera, el cual se utiliza para evitar que el mismo código de la cabecera se

repita si esta misma cabecera es incluida en algún otro archivo fuente.

Para poner el protector se utilizan el siguiente código del preprocesador:

#ifndef NOMBRECABECERA_H #define NOMBRECABECERA_H // Interface o contenido de cabecera #endif

Page 2: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

2

2. La segunda parte es la interface o contenido de cabecera que consiste en:

Cabeceras adicionales:

o #include <stdio.h>

o #include “suma.h”

Constantes, enumeraciones y redefiniciones de tipo:

o const unsigned char total;

o enum numeros {cero,uno,dos,tres,cuatro,cinco,seis,siete,ocho,nueve,diez}

o typedef unsigned char u8;

Definición de estructuras, uniones y arreglos.

o struct Reloj { unsigned char Hora; unsigned char Minuto; unsigned char Segundo };

o unión { unsigned int Valor; struct { unsigned char LSB; unsigned char MSB } };

Instrucciones del preprocesador:

o #define MAX_VOL 25

o #define, #ifdef, #ifndef, #undef, #if, #elif, #else, #endif, #error

Declaraciones de funciones (prototipos):

o unsigned char funcion1(unsigned char);

o void funcion2(void);

Comentarios sobre el uso de cada función.

Consejos prácticos sobre la cabecera:

Incluir siempre protectores de cabecera.

Incluir solamente las cabeceras adicionales que sean necesarias.

Declarar constantes, definición de estructuras y uniones, no variables.

Declarar las funciones (prototipos), no las definiciones.

Cada cabecera debe tener una tarea en específica.

Archivo Fuente: El archivo fuente (“source file” en ingles) son archivos con extensión “*.c” y tienen el objetivo de definir todo lo

declarado en la cabecera o interface del modulo, también define funciones o variables de uso interno (privadas).

Se componen de:

Cabecera correspondiente al archivo fuente:

o #include “cabecera”

Variables externas, entre otras:

o unsiged char Variable;

Definición de las funciones:

o unsigned char funcion1(unsigned char valor) { return valor * 2; }\

Page 3: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

3

Ejemplo 1: Suma (Nivel principiante) Para el primer ejemplo utilizaremos un programa muy básico que suma dos valores de 8 bits sin signo e imprime el

resultado.

Originalmente el programa principal y el modulo están contenidos en el mismo archivo:

main.c (original)

1. /*

2. * Autor: Omar Gurrola

3. * Fecha: 10/10/12

4. * Sitio: http://www.proprojects.wordpress.com

5. *

6. * Archivo: main.c

7. * Titulo: ANSIC: Cabecera y Archivo Fuente

8. * Descripción: Ejemplo 1: Suma (Nivel principiante)

9. * Compilador: Microchip C18 v3.4

10. */

11. #include <stdio.h> // printf();

12. // Definición o prototipo de suma() 13. unsigned int suma(unsigned char, unsigned char);

14. // Programa principal 15. void main(){ 16. // Variables de entrada y salida

17. unsigned char a,b;

18. unsigned int c;

19. // Valores iniciales

20. a = 255;

21. b = 255;

22. // Realizamos la suma utilizando la función suma();

23. c = suma(a,b);

24. // Imprimimos el resultado de la suma

25. printf("El resultado de la suma es: %u\n");

26. }

27. // Definición de la función suma() 28. unsigned int suma(unsigned char x, unsigned char y){ 29. return (unsigned int)x + (unsigned int)y;

30. }

Page 4: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

4

Para segmentar este programa lo primero que haremos es crear la cabecera e interface llamada “suma.h” utilizando la

definición de suma(); (main.c-línea: 13), quedando de la siguiente manera:

La declaración de suma(); (main.c-líneas: 28-30) se define en el archivo fuente llamado “suma.c” y se debe añadir la

cabecera correspondiente al modulo (suma.c-línea 12) de la siguiente manera:

suma.h

1. /* 2. * Autor: Omar Gurrola 3. * Fecha: 10/10/12 4. * Sitio: http://www.proprojects.wordpress.com 5. * 6. * Archivo: suma.h 7. * Titulo: ANSIC: Cabecera y Archivo Fuente 8. * Descripción: Ejemplo 1: Suma (Nivel principiante) 9. * Compilador: Microchip C18 v3.4 10. */

11. // Protector de cabecera 12. #ifndef SUMA_H 13. #define SUMA_H 14. // Definición o prototipo de suma() 15. unsigned int suma(unsigned char, unsigned char); 16. #endif

suma.c

1. /* 2. * Autor: Omar Gurrola 3. * Fecha: 10/10/12 4. * Sitio: http://www.proprojects.wordpress.com 5. * 6. * Archivo: suma.c 7. * Titulo: ANSIC: Cabecera y Archivo Fuente 8. * Descripción: Ejemplo 1: Suma (Nivel principiante) 9. * Compilador: Microchip C18 v3.4 10. */

11. // Includes 12. #include "suma.h"

13. // Definición de la función suma() 14. unsigned int suma(unsigned char x, unsigned char y){ 15. return (unsigned int)x + (unsigned int)y; 16. }

Page 5: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

5

Para terminar, al programa principal le añadimos la cabecera del modulo “suma.h” (main.c-línea 12) y solamente

utilizamos la función definido en ese modulo (línea: 22), quedando de la siguiente manera:

main.c

1. /* 2. * Autor: Omar Gurrola 3. * Fecha: 10/10/12 4. * Sitio: http://www.proprojects.wordpress.com 5. * 6. * Archivo: main.c 7. * Titulo: ANSIC: Cabecera y Archivo Fuente 8. * Descripción: Ejemplo 1: Suma (Nivel principiante) 9. * Compilador: Microchip C18 v3.4 10. */

11. #include <stdio.h> // printf(); 12. #include "suma.h" // suma();

13. // Programa principal 14. void main(){ 15. // Variables de entrada y salida 16. unsigned char a,b; 17. unsigned int c;

18. // Valores iniciales 19. a = 255; 20. b = 255;

21. // Realizamos la suma utilizando la función suma(); 22. c = suma(a,b);

23. // Imprimimos el resultado de la suma 24. printf("El resultado de la suma es: %u\n"); 25. }

Page 6: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

6

El proceso para crear nuestra aplicación se realiza de la siguiente manera:

1. Todas las cabeceras incluidas en cada archivos fuentes con añadidas al mismo.

2. Cada archivo fuente es compilado y convertido en un archivo con extensión “*.o”.

3. Por ultimo cada archivo objeto “*.o” y librerías utilizadas son ligados correctamente para obtener el programa

final.

Page 7: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

7

Ejemplo 2: Pila LIFO (Nivel intermedio) Para este ejemplo implementaremos una pila LIFO (Last In First Out) en un modulo para que pueda ser reutilizada en

cualquier proyecto futuro.

La pila LIFO consiste en un arreglo donde podemos meter y sacar datos, con la característica de que el último

dato en entrar es el primero en salir, esta pila es la mas sencilla de implementar.

Lo primero es definir todo lo que se requiere para la interface:

El protector de cabecera (Líneas: 12,13 y 44).

El tipo de datos que almacenara la pila (Línea: 17).

El tipo de dato que regresara la pila si hubo un error (Línea: 18).

El tipo de dato para alojar el índex de la pila (Línea: 19).

El tamaño de la pila (Línea: 20).

Constantes para regresar ERROR=0 y OK=1 (Línea: 21).

Definición de función para meter un dato a la pila (Línea: 29).

Definición de función para sacar un dato en la pila (Línea: 36).

Definición de función para borrar toda la pila (Línea: 43).

Comentarios de cada configuración y de los prototipos para su uso.

lifostack.h

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: lifostack.h

7. * Description: LIFO Stack Header

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. #ifndef LIFOSTACK_H 13. #define LIFOSTACK_H

14. /** INCLUDES *******************************************************/ 15. //#include <>

16. /** INTERFACE CONFIGURATION ****************************************/ 17. typedef unsigned char LIFOSTACK_TYPE; // Stack type

18. typedef unsigned char LIFOSTACK_RESULT; // Result type (Just return 0 or 1)

19. typedef unsigned char LIFOSTACK_INDEX_TYPE; // Enough bits to fit LIFOSTACK_SIZE

20. #define LIFOSTACK_SIZE 20 // Stack size

21. enum {LIFOSTACK_RETURN_FAIL=0,LIFOSTACK_RETURN_OK=1}; // Functions return

22. /** PROTOTYPES *****************************************************/ 23. /******************************************************************* 24. * Function: LIFOSTACK_RESULT lifostack_push(LIFOSTACK_TYPE);

25. * Input: Value to be pushed in the stack

26. * Output: Result: 1 = Value pushed, 0 = Push fail because stack is full

27. * Description: Push a value of type LIFOSTACK_TYPE to stack

28. *******************************************************************/ 29. LIFOSTACK_RESULT lifostack_push(LIFOSTACK_TYPE);

Page 8: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

8

30. /******************************************************************* 31. * Function: LIFOSTACK_RESULT lifostack_push(LIFOSTACK_TYPE *);

32. * Input: Pointer of type LIFOSTACK_TYPE to store extracted value

33. * Output: Result: 1 = Value extracted, 0 = Pop fail because stack is empty

34. * Description: Pop a value of type LIFOSTACK_TYPE from stack

35. *******************************************************************/ 36. LIFOSTACK_RESULT lifostack_pop(LIFOSTACK_TYPE *);

37. /******************************************************************* 38. * Function: void lifostack_clear(void);

39. * Input: None

40. * Output: None

41. * Description: Clear FIFO Stack

42. *******************************************************************/ 43. void lifostack_clear(void);

44. #endif // LIFOSTACK_H

Page 9: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

9

Teniendo bien definida nuestra cabecera e interface podemos proceder a crear el archivo fuente en el cual vamos a

realizar lo siguiente:

Incluir la cabecera del modulo (Línea: 13).

Definir el arreglo privado que se utilizara de pila (Línea: 15).

Definir el índex privado que se utilizara para administrar la pila y debe iniciar en cero (Línea: 16).

La definición de la función para meter un dato (Líneas: 18-26).

La definición de la función para sacar un dato (Líneas: 27-35).

La definición de la función para borrar toda la pila (Líneas: 36-38).

Todo el modulo debe estar comentado preferentemente.

lifostack.c

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: lifostack.c

7. * Description: LIFO Stack Source File

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. /** INCLUDES *******************************************************/ 13. #include "lifostack.h"

14. /** MODULE PRIVATE *************************************************/ 15. LIFOSTACK_TYPE lfstack[LIFOSTACK_SIZE]; // Array for LIFO Stack

16. LIFOSTACK_INDEX_TYPE index = 0; // index of stack

17. /** FUNCTION DEFINITIONS *******************************************/ 18. LIFOSTACK_RESULT lifostack_push(LIFOSTACK_TYPE value){ 19. if(index < LIFOSTACK_SIZE){ // Before push a value check if stack is full.

20. lfstack[index++] = value; // Stack is not full, so push new value in stack and increment index after.

21. return LIFOSTACK_RETURN_OK; // Return OK.

22. }

23. else{ // Stack is full.

24. return LIFOSTACK_RETURN_FAIL; // Do nothing and return FAIL.

25. }

26. }

27. LIFOSTACK_RESULT lifostack_pop(LIFOSTACK_TYPE *pvalue){ 28. if(index > 0){ // Before pop a value check if stack is empty.

29. *pvalue = lfstack[--index]; // Stack isn't empty, so pop a value and decrement index before.

30. return LIFOSTACK_RETURN_OK; // Return OK.

31. }

32. else{ // Stack is empty.

33. return LIFOSTACK_RETURN_FAIL; // Do nothing and return FAIL.

34. }

35. }

36. void lifostack_clear(void){ 37. index = 0; // To clear stack just put index to cero.

38. }

Page 10: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

10

Tendiendo todo el modulo listo procedemos a incluir la cabecera “lifostack.h” y el archivo fuente “lifostack.c” al

proyecto y en “main.c” añadimos la cabecera “lifostack.h” para poder utilizar el modulo, probaremos el modulo de la

siguiente manera:

Primero llenaremos toda la pila (Líneas: 17-24).

Luego sacaremos todos los datos de la pila (Líneas: 26-33).

Después llenaremos la pila e intentaremos meter cinco datos mas, los cuales no nos debe permitir (Líneas: 35-

42).

Procedemos a vaciar la pila (Línea: 44)

Por ultimo intentamos sacar cinco datos, los cuales no nos debe permitir (Líneas: 45-52).

main.c

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: main.c

7. * Description: Example of LIFO Stack

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. #include <stdio.h> // printf();

13. #include "lifostack.h" // lifostack_push(); lifostack_pop();

14. void main(){ 15. unsigned char x,z;

16. // First let’s push full stack

17. for(x=0;x<LIFOSTACK_SIZE;x++){

18. if(lifostack_push(x)){

19. printf("Push Value: %u\n",x);

20. }

21. else{

22. printf("Stack is full!!\n");

23. }

24. }

25. // Next let’s pop full stack

26. for(x=0;x<LIFOSTACK_SIZE;x++){

27. if(lifostack_pop(&z)){

28. printf("Pop Value: %u\n",z);

29. }

30. else{

31. printf("Stack is empty!!\n");

32. }

33. }

34. // Now let’s overfill stack with LIFOSTACK_SIZE + 5

35. for(x=0;x<LIFOSTACK_SIZE+5;x++){

36. if(lifostack_push(x)){

37. printf("Push Value: %u\n",x);

38. }

39. else{

40. printf("Stack is full!!\n");

41. }

42. }

Page 11: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

11

43. // Now let’s clear the stack and try to pop 5 values

44. lifostack_clear();

45. for(x=0;x<5;x++){

46. if(lifostack_pop(&z)){

47. printf("Pop Value: %u\n",z);

48. }

49. else{

50. printf("Stack is empty!!\n");

51. }

52. }

53. }

Page 12: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

12

Ejemplo 3: Pila FIFO (Nivel intermedio) Para este ejemplo desarrollaremos el modulo de una pila FIFO (First In First Out), no entrare mucho en detalle ya que se

diseña y segmenta de la misma forma que el ejemplo 3, con la única diferencia de que cambia el algoritmo para

administrar la pila.

fifostack.h

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: fifostack.h

7. * Description: FIFO Stack Header

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. #ifndef FIFOSTACK_H 13. #define FIFOSTACK_H

14. /** INCLUDES *******************************************************/ 15. //#include <>

16. /** INTERFACE CONFIGURATION ****************************************/ 17. typedef unsigned char FIFOSTACK_TYPE; // Stack type

18. typedef unsigned char FIFOSTACK_RESULT; // Result type (Just return 0 or 1)

19. typedef unsigned char FIFOSTACK_INDEX_TYPE; // Enough bits to fit STACK_SIZE

20. #define FIFOSTACK_SIZE 20 // Stack size

21. enum {FIFOSTACK_RETURN_FAIL=0,FIFOSTACK_RETURN_OK=1}; // Functions return

22. /** PROTOTYPES *****************************************************/ 23. /******************************************************************* 24. * Function: FIFOSTACK_RESULT fifostack_push(FIFOSTACK_TYPE);

25. * Input: Value to be pushed in the stack

26. * Output: Result: 1 = Value pushed, 0 = Push fail because stack is full

27. * Description: Push a value of type FIFOSTACK_TYPE to stack

28. *******************************************************************/ 29. FIFOSTACK_RESULT fifostack_push(FIFOSTACK_TYPE);

30. /******************************************************************* 31. * Function: FIFOSTACK_RESULT fifostack_push(FIFOSTACK_TYPE *);

32. * Input: Pointer of type FIFOSTACK_TYPE to store extracted value

33. * Output: Result: 1 = Value extracted, 0 = Pop fail because stack is empty

34. * Description: Pop a value of type FIFOSTACK_TYPE from stack

35. *******************************************************************/ 36. FIFOSTACK_RESULT fifostack_pop(FIFOSTACK_TYPE *);

37. /******************************************************************* 38. * Function: void fifostack_clear(void);

39. * Input: None

40. * Output: None

41. * Description: Clear FIFO Stack

42. *******************************************************************/ 43. void fifostack_clear(void);

44. #endif // FIFOSTACK_H

Page 13: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

13

fifostack.c

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: fifostack.c

7. * Description: FIFO Stack Source File

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. /** INCLUDES *******************************************************/ 13. #include "fifostack.h"

14. /** MODULE PRIVATE *************************************************/ 15. FIFOSTACK_TYPE ffstack[FIFOSTACK_SIZE]; // Array for FIFO Stack

16. FIFOSTACK_INDEX_TYPE counter = 0; // counter of stack

17. FIFOSTACK_INDEX_TYPE in = 0; // in index

18. FIFOSTACK_INDEX_TYPE out = 0; // out index

19. /** FUNCTION DEFINITIONS *******************************************/ 20. FIFOSTACK_RESULT fifostack_push(FIFOSTACK_TYPE value){ 21. if(counter < FIFOSTACK_SIZE){ // Before push a value check if stack is full.

22. ffstack[in++] = value; // Stack is not full, so push new value in stack.

23. counter++; // One more element in the stack

24. if(in == FIFOSTACK_SIZE){ // If in reach STACK_SIZE.

25. in = 0; // Reset to cero.

26. }

27. return FIFOSTACK_RETURN_OK; // Return OK.

28. }

29. else{ // Stack is full.

30. return FIFOSTACK_RETURN_FAIL; // Do nothing and return FAIL.

31. }

32. }

33. FIFOSTACK_RESULT fifostack_pop(FIFOSTACK_TYPE *pvalue){ 34. if(counter > 0){ // Before pop a value check if stack is empty.

35. *pvalue = ffstack[out++]; // Stack isn't empty, so pop a value.

36. counter--;

37. if(out == FIFOSTACK_SIZE){ // If out reach STACK_SIZE.

38. out = 0; // Reset to cero.

39. }

40. return FIFOSTACK_RETURN_OK; // Return OK.

41. }

42. else{ // Stack is empty.

43. return FIFOSTACK_RETURN_FAIL; // Do nothing and return FAIL.

44. }

45. }

46. void fifostack_clear(void){ 47. counter = 0; // counter to cero.

48. in = 0; // in to cero

49. out = 0; // out to cero

50. }

Page 14: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

14

main.c

1. /*********************************************************************

2. * By: Omar Gurrola

3. * Company: http://proprojects.wordpress.com

4. * Processor: PIC18

5. * Compiler: C18 v3.4

6. * File Name: main.c

7. * Description: Example of FIFO Stack

8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

9. * Rev. Date Comment

10. * 1.0 10/10/12 Initial version 11. ********************************************************************/

12. #include <stdio.h> // printf();

13. #include "fifostack.h" // fifostack_push(); fifostack_pop(); fifostack_clear();

14. void main(){ 15. unsigned char x,z;

16. // First let’s push full stack

17. for(x=0;x<FIFOSTACK_SIZE;x++){

18. if(fifostack_push(x)){

19. printf("Push Value: %u\n",x);

20. }

21. else{

22. printf("Stack is full!!\n");

23. }

24. }

25. // Next let’s pop full stack

26. for(x=0;x<FIFOSTACK_SIZE;x++){

27. if(fifostack_pop(&z)){

28. printf("Pop Value: %u\n",z);

29. }

30. else{

31. printf("Stack is empty!!\n");

32. }

33. }

34. // Now let’s overfill stack with FIFOSTACK_SIZE + 5

35. for(x=0;x<FIFOSTACK_SIZE+5;x++){

36. if(fifostack_push(x)){

37. printf("Push Value: %u\n",x);

38. }

39. else{

40. printf("Stack is full!!\n");

41. }

42. }

43. // Now let’s clear the stack and try to pop 5 values

44. fifostack_clear();

45. for(x=0;x<5;x++){

46. if(fifostack_pop(&z)){

47. printf("Pop Value: %u\n",z);

48. }

49. else{

50. printf("Stack is empty!!\n");

51. }

52. }

53. }

Page 15: ANSI C: Cabecera y Archivo Fuente

Por: Omar Gurrola http://www.proprojects.wordpress.com Versión: v1.0 [10/10/12]

15

Referencias

Computación Gráfica FI, “Archivos de cabecera en C++”, 29/03/08,

http://computaciongrafica.wordpress.com/2008/03/29/archivos-de-cabecera-en-c/.

Alex, “1.9 – Header files”, 03/06/07, http://www.learncpp.com/cpp-tutorial/19-header-files/.

Dave Marshall, “Writing Larger Programs”, 05/01/99, http://www.cs.cf.ac.uk/Dave/C/node35.html.

Brian W. Kernighan, Dennis M. Ritchie, “The C Programming Language”, Second Edition.