Un pequeño inciso para comentar una serie de cosas que pueden resultar útiles para familiarizarnos un poco más con el uso de variables y procedimientos(rutinas).
AMBITO DE LAS VARIABLES:
Dependiendo del lugar donde sea declarada,una variable podrá ser visible o no desde una parte concreta de nuestro código.
Si la declaramos como variable global,su ámbito(alcance) será todo el programa,por lo que podremos consultar o modificar su valor desde el main o desde cualquiera de los procedimientos de nuestro código.La pega es que hacer uso de variables globales no es lo más recomendado,no por una cuestión formal,sino porque estarán ocupando memoria durante toda la ejecución aunque no las usemos,y eso no interesa.
Así,si lo que queremos es optimizar los recursos del micro,lo bueno es reducir al máximo el ámbito de las variables y que éstas estén localizadas en segmentos concretos del código.
Un ejemplo:
Codigo:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include "lcd.c"
int numero1; // Esta variable es global,por lo que ocupará 1 byte durante
// toda la ejecución
void suma()
{
// numero2 está localizada en este procedimiento,por lo que su ámbito es
// exclusivamente este procedimiento y no será visible desde ningún otro sitio.
// ¿Qué ganamos con ello? Pues es sencillo,cuando suma() es llamado desde el main,
// lo primero que ocurre es que se crea la variable numero2,que ocupará 1 byte
// en algún lugar de la memoria.Cuando suma() termina de ejecutarse,ese byte
// quedará liberado para que otro dato pueda usarlo si fuera necesario.
// Conclusión: se optimiza memoria
int numero2;
numero2 = 15;
numero1 = numero1 + numero2; // Modificamos el valor de nuestra variable global
}
void main()
{
lcd_init();
numero1 = 10; // La vemos porque es global
suma(); // Llamada al procedimiento suma()
printf(lcd_putc,"%u",numero1); // La mostramos en el lcd
for(; {}
}
Ya no es sólo cuestión de optimizar memoria,así se consigue también un código más estructurado y modularizado.
A otra cosa,mariposa.
PARAMETROS POR VALOR O POR REFERENCIA:
Como se ve en un ejemplo que hay un poco más arriba,también se puede conseguir que una variable sea visible,para que podamos usarla,dentro de una rutina en la que no está declarada.La forma de hacerlo es enviar dicha variable como parámetro cuando se efectúa la llamada al procedimiento...¡¡Ponme un ejemplo!!:-/
Codigo:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include "lcd.c"
void suma(int num1,int num2,long int &res)
{
// "num1" y "num2" son parámetros de entrada.
// "res" es de entrada-salida.
// "num1" es un parámetro de entrada por valor.Al ser un parámetro de entrada,cuando se produce
// la llamada al procedimiento,se crea una copia de dicho valor y el procedimiento
// trabaja con dicha copia,y no con el original como cabe pensar.
// "num2" es otro parámetro pasado por valor.Al ser sólo de entrada,también se crea una copia en
// memoria con la que trabajaremos y que será destruída,al igual que "num1",cuando
// acabe la ejecución de la rutina.
// Por último nuestro parámetro de entrada-salida.Ni que decir tiene que un parámetro
// de entrada-salida JAMAS DE LOS JAMASES es pasado por valor,siempre lo es por referencia y
// deberá tener SIEMPRE como origen una variable.
// Esta vez,al ser un parámetro de entrada-salida,susceptible de ser modificado,el
// el procedimiento no hace copia ninguna y trabaja con el original de forma dinámica
// ¿qué quiere decir eso? Pues que se crea un puntero que apuntará al dato de origen y la
// rutina trabajará con ese puntero en vez de hacerlo directamente con el dato.
res = num1 + num2; // Asiganmos a "res" la suma de los otros 2 parámetros
}
void main()
{
// Declarar variables en el programa principal es casi como declararlas globales,
// por lo que tampoco es lo más óptimo.
int numero;
long int resultado;
lcd_init();
resultado = 0; // Esta acción es superflua ya que vamos a modificar su valor en breve.
// suma() lleva 3 parámetros: uno por valor y dos por referencia.
suma(numero,23,resultado); // Llamada al procedimiento suma()
// "resultado" ha sido modificado y devuelto por el procedimiento suma()
printf(lcd_putc,"%lu",resultado); // La mostramos en el lcd
for(; {}
}
Para ver más claro esto de las copias de los parámetros y tal,una vez compilado el programa,se puede ver la distribución de los datos en la memoria del pic en el menú de CCS:
View -> Symbol map
Saludos