Pedmar el tema del ámbito de existencia de las variables es una cuestión que necesita ser explicada muy temprano, pero no es fácil de entender hasta que ya se han practicado con ellas.
Para manejar programas sencillos no es necesario dominar un tema que si se intenta explicar en toda su amplitud a un novato provocará el rechinar de neuronas.
Lo básico es empezar comprendiendo el funcionamiento de las variables globales y de las variables locales.
Las variables globales son aquellas que se declaran fuera de una función y que generalmente se ponen al principio de los programas, (podrían ponerse en otra parte pero siempre fuera de las funciones), tienen una existencia global al programa. Pueden accederse desde dentro de cualquier función salvo que en una función se declare una variable con el mismo nombre, ya que la ocultaría.
Dentro de las funciones se pueden declarar variables pero estas solo tendrán existencia dentro de la función y al salir de la función se destruye.
Podría decirse que una variable es un trozo de memoria con un determinado tamaño y que tiene asociado un tipo de dato. Sirven de contenedores para guardar valores. Para cambiar su contenido se escribe en la memoria un contenido diferente. No es como una caja que puede estar vacía. Siempre contienen algo.
Las variables globales se crean en el mismo momento en que se declaran antes de que se ejecute nada, pero las variables locales se crean en el momento de ejecutarse la función. Eso implica crear ese espacio disponible en memoria para contener el tipo de dato contenido.
Dicho así parece simple pero hay que comprender que desde dentro de una función se puede llamar a otras y desde esas a otras y todo tiene que funcionar por complejo que sea el anidamiento de unas llamadas dentro de otras. Pensemos que hay funciones que se pueden usar con mucha frecuencia desde muchas otras que a su vez pueden llamarse entre sí. Al igual que una variable local puede ocultar a una variable global con el mismo nombre sin destruirla, dentro de una función no se podrá acceder a otras variables locales.
Dentro de una funcion se pueden declarar variables no solo al principio sino en cualquier parte. La variable no existirá hasta que se declare. Se crea en ese mismo instante.
Los argumentos que se pasan a una función son como variables locales, pero que van a recibir un valor en la llamada a la función.
Si ponemos la declaración de una variable dentro de un bloque entre llaves { } las variables se crean en ese bloque y se destruyen al salir del bloque y un bloque permite sustituir una sentencia por una serie de sentencias.
Por ejemplo:
if (condicion){
int variableInternaAlbloque;
...;
...;
...;
}
Desde dentro de una función, nada impide llamar a la propia función. Eso es un poco complicado de entender como funciona y se llama recursividad. Lo que ocurre en estos casos es que las variables locales de la primera llamada continúan existiendo con independencia de las variables de la segunda llamada pese a tener el mismo nombre. Las variables dentro de la nueva llamada ocultaran a las variables homónimas de llamadas previas como si fuera variables locales de otras funciones diferentes.
Por ejemplo, yo podría definir una función que llamaremos función factorial y dentro del códido indicar al ordenador que el factorial de un número es ese número multiplicado por el factorial de ese número menos uno. Parece raro que en la forma de resolver un problema hagamos una llamada a la misma función factorial, eso sí con el número decrementado.
De hecho, tal cual acabo de explicarlo no funcionaría porque si no ponemos algo más, la función se llamaría a si misma contínuamente hasta agotar toda la memoria. Eso ocorriría porque no damos ninguna opción a salir de ninguna de esas llamadas salvo llamándose otra vez a sí misma y cada una de esas llamadas consume memoria para crear sus propias variables locales, que aúnque tengan el mismo nombre, podrán contener un valor diferente.
Lo único que se necesita para que la recursivida funcione es que la función factorial consulte antes que nada si el número cuyo factorial deseamos obtener es uno y en ese caso devolvemos como resultado el valor uno ( 1!= 1), en caso contrario diremos que el resultado es el número multiplicado por factorial del número.
Si ponemos un número muy alto podría agotar la memoria, y cascar, en caso contrario cuando las llamadas una dentro de otras lleguen a preguntar por el factorial de 1 empezaran a salir de cada una de las llamadas devolviendo el resultado a la llamada anterior hasta terminar.
Código:
int Factorial(int n) {
if (n <= 1)
return 1;
else
return (n * Factorial(n-1));
} // end Factorial
Factorial de N se representa por N!
4! = 4 * 3! ---> necesita llamar nuevamente a factorial
3!= 3 * 2! ---> necesita llamar nuevamente a factorial
2!= 2 *1! ---> necesita llamar nuevamente a factorial
2!= 2*1 ---> el factorial de 1 es 1, retornamos resultado
3! = 3* (2*1) ---> retornamos resultado
4! = 4 * (3 * (2*1)) ---> retornamos resultado
Es evidente que este problema se resuelve más fácil con un simple bucle, pero es un ejemplo sencillo de como funcionaría una función llamándose a sí misma.
Pedmar, una de las cosas que te recomiendo practicar es intercalar dentro de tus programa código de trazas.
Son instrucciones para mostrar el valor de alguna variable.
Por ejemplo:
Serial.println("La variable X contiene ");
Serial.println(X);
De esa forma puede ir intentando ver lo que ocurre.
No sigo para no agobiar.
Pedmar, pregunta lo que quieras y tranquilo, yo sé perfectamente donde me meto, y creo que es imprescindible ayudar un poco al comienzo que es lo que más cuesta.