documentación para el trabajo con la plataforma guadalbot
Transcripción
documentación para el trabajo con la plataforma guadalbot
DOCUMENTACIÓN PARA EL TRABAJO CON LA PLATAFORMA GUADALBOT I.E.S VIRGEN DE LAS NIEVES Programación C para microcontroladores Tema 4. Funciones Índice de contenidos Definición.............................................................................................................................................2 Paso de parámetros por valor...............................................................................................................3 Paso de parámetros por referencia........................................................................................................3 Prototipado y ámbito de funciones.......................................................................................................4 1 Definición Una función es una parte de código independiente del programa principal que realiza una determinada acción cuando es llamada. Esta llamada puede hacerse enviándole (o no) datos para que realice su tarea y proporcione (o no) unos resultados. Definir una función consiste en implementar el código necesario para que realice las tareas para las que la vamos a definir, teniendo una sintaxis que podemos basar en la siguiente idea. tipo_dato1 ident_func (tipo_dato2 arg1, tipo_dato3 arg2, ... ) { //Bloque de código return dato; //Necesario sólo si la función retorna algún valor } Para definir una función debemos seguir los siguiente pasos: 1. tipo_dato1: Indicamos el tipo del valor de retorno, que será cualquiera de los tipos vistos. Si la función no tiene valor de retorno el tipo será void (vacío, sin nada). 2. ident_func: Nombramos al identificador de la función, que es el nombre de la misma y que puede ser un identificador válido cualquiera. Este será el nombre por el que se la conocerá. 3. tipo_dato2 arg1, tipo_dato3 arg2, ...: Definimos los parámetros (variables arg1, arg2, ...) de los tipos apropiados que necesite para operar. Estas variables son las que recibirán los datos que se le pasen a la función. Si no existen parámetros el nombre de la función irá seguido de unos paréntesis vacíos. 4. Bloque de código a ejecutar delimitado entre llaves. En este bloque de código la función puede declarar sus propias variables, tipos, etc de forma local. 5. return dato: Si la función debe retornar algún valor es en esta sentencia donde debemos indicarlo. El valor de retorno es el valor que una función puede devolver al programa que la ha llamado y una vez que se ejecuta la misma. El tipo se debe especificar en el encabezado de la función, que si no se especifica se supone int. Si no queremos que la función retorne ningún valor debemos especificar como tipo para el retorno el tipo void. 6. Si queremos devolver el control al programa que hace la llamada a la función debemos usar la sentencia return, pudiendo coexistir varias sentencias de este tipo en una misma función. En caso de no situar ninguna sentencia return el control se devolverá cuando se complete la ejecución del cuerpo de la función. La palabra return puede ir seguida de una expresión, que será evaluada y el valor resultante devuelto al programa que llama como valor de retorno, si es necesario con una conversión al tipo indicado en el encabezado. El valor de retorno es un valor único. 7. Para llamar a la función en cualquier punto del código del programa bastará con utilizar el identificador o nombre de la misma. La forma más sencilla de función es la que vemos en el ejemplo siguiente, que no devuelve ni recibe nada. void nombre_funcion (void) { //Bloque de código } Para llamar a esta función basta escribir una línea de código como la siguiente: nombre_funcion(); 2 Paso de parámetros por valor Se trata de hacer que la función sea más flexible pudiendo recibir datos desde otra parte del código del programa que no sea la propia función. Los parámetros que va a recibir una función se indican en la declaración entre paréntesis. La declaración es similar a la de una variable, es decir, indicamos los tipos y los nombres y usamos la coma para separar unos de otros. Cuando llamamos a una función con parámetros es importante respetar el orden y el tipo de los parámetros que esta recibe. El primer valor pasado corresponde al primer parámetro de entrada; el segundo valor, al segundo parámetro; y así sucesivamente. Un sencillo ejemplo aclara lo dicho. El mecanismo funciona así: siempre respetando el orden, al llamar a la función el valor 10 se copiará a la variable x; el valor 20 a la y, y el valor 30 a z. Después de ejecutarse el código de la función, el valor de retorno (suma en este caso) será copiado a una variable temporal y de allí pasará a resultado ya en la función principal. Paso de parámetros por referencia Hemos visto como en el paso de parámetros por valor las variables locales no tienen relación con los parámetros salvo por su valor, por lo que si modificamos el valor de las variables locales no afectamos para nada a los parámetros. Si lo que queremos pasar a la función no es el valor del parámetro, sino el parámetro en si mismo debemos pasarselo por referencia. El paso de parámetros por referencia a una función hace que esta cree un identificador local que recibe la dirección de la variable original en lugar del valor del parámetro, permitiendo que su valor pueda usarse a voluntad para realizar tareas o para modificarlo. Es decir, que se crea un segundo nombre para la misma variable como identificador local en el momento de la llamada a la función. Este nuevo nombre se destruye cuando finaliza la función. Las direcciones deben recibirse como variables puntero, por lo que los argumentos de la función deberán ser punteros. 3 Prototipado y ámbito de funciones El prototipado de una función le informa al compilador de sus características así como de su tipo de retorno, el número de parámetros que espera recibir, el tipo y orden de dichos parámetros. Por esto lo aconsejable es declarar el prototipo al inicio del programa, como si de una directiva se tratase. El prototipo de una función es muy parecido a su encabezado, sólo se van a diferenciar porque el prototipo terminar en un punto y coma (;). Lo correcto en el ejemplo anterior sería hacer lo que vemos a continuación. Si las funciones no tienen prototipo, el acceso a ellas será restringido. El compilador solo 'verá' las funciones que están implementadas antes de la función que las llama o, de lo contrario, mostrará errores de “función no definida”. Hablamos de ámbito global cuando los identificadores (variables, funciones, etc.) Se definen de forma externa a cualquier bloque de código. El identificador de una función tiene ámbito global, lo que significa que puede ser usado desde cualquier parte del programa en el que se ha definido incluidas otras funciones del programa. Cuando los identificadores (variables, otras funciones, etc.) forman parte del cuerpo de la función hablamos de identificadores locales y, estos, solamente son accesibles desde el interior del cuerpo de la función, nunca desde fuera. Es decir, el bloque principal del programa no puede acceder a las variables locales de una función, como tampoco una función puede acceder a los identificadores locales de otra función; siendo los identificadores globales los únicos accesibles desde cualquier punto. Las variables locales de la función se crean cada vez que se ejecuta la función y permanecen ocultas para el resto del programa. Si estas variables de definen como static, conservan su valor entre distintas llamadas a la función. Las variables globales pueden hacerse visibles para una función si las declaramos como extern. 4