Joan Soler-Adillon || Programació: Conceptes
Despatx 234 || 935 421 484
![]()
----------------------------------------------------------------
----------------------------------------------------------------
PROGRAMACIÓN: CONCEPTOS || MASTER EN ARTES DIGITALES
Sessión 7;
1. Funciones
2. Parámetros
3. Retorno
4. Más ejemplos
5. PRACTICA
Las funciones nos sirven para organizar el código y poderlo reciclar luego. Una función es una estructura que en un momento dado en el flujo del programa es invocada. Cuando esto pasa, las instrucciones que estén contenida en la función se van a ejecutar.
Podemos volver al ejemplo de la luz del segundo día, donde el programa decidía si era yo o un alumno, según la distancia de cada uno hacia la puerta, quien debía ir a cerrarla. Una vez tomada la decisión, no basta, de hecho, para que la puerta sea cerrada. Ir a cerrar la puerta es una acción compleja que consta de varias acciones concretas, que cuando estamos hablando de programación habrá que explicitar:
Estas acciones se pueden explicitar en el código principal, lo que en Processing sería el DRAW o bién puede crearse una función que las englobe (abrirLaPuerta), y que en el código principal sólamente tenga que invocarse esta función cada vez que se tenga que cerrar una puerta.
Así, podemos dibujar el Rebicho que vimos en la segunda sesión con una sola línea en el draw, y todo el código del dibujo contenido en una sola función, de manera que el DRAW nos queda así:
Aquí, dibujaRebicho(); invoca una función que hemos creado para dibujar el animalito. Cuando llamamos la función, lo hacemos por su nombre, seguido de paréntesis. En el caso de una función que no recibe parámetros (como este), simplemente habrimos y cerramos paréntesis sin más para indicar a java que nos estamos refiriendo a una función.
Para crear la función, hay que tener en cuenta dos cosas. Si hay retorno (si devuelve o no algún valor), y si tiene parámetros. Como dedicamos a éstas dos cosas sendos apartados en esta sesión, de momento nos centraremos en funciones que no retornan nada y no reciben parámetros.
También sería el caso siguiente, donde utilizamos una función para hacer otro dibujo:
void setup(){
size(200,200);
}
void draw(){
background(0);
smooth();
//invocamos la función, que definimos más adelante:
dibujaUnSputnik();
}
//He aquí una función que dibuja un SPUTNIK:
void dibujaUnSputnik(){
strokeWeight(3);
stroke(255);
fill(255,0,0);
line(70,70,130,130);
line(70,130,130,70);
ellipse(100,100,35,35);
}
Aquí podemos ver cómo declaramos una función:
El void debería sonar del SETUP y el DRAW. Es la palabra clave que indica que la función no retorna nada. De la misma manera, los paréntesis en blanco indican que la función no recibe parámetros.
Lo que estas dos cosas significan es que una función así se invocará de la siguiente manera:
Simplemente llamando la función por su nombre y los paréntesis en blanco provocaremos que en el punto en el código donde la función es invocada, el flujo de acciones salta hacia la llave donde empiezan las instrucciones de la función, sigue hasta que la función se cierra, y continúa luego hacia la línea que sigue la invocación. En el ejemplo, vuelve a empezar el DRAW.
2.- Parámetros
Lo que vimos hasta ahora no pasa de ser una mejor organización del código. Las funciones empiezan a ser mucho más interesantes cuando empezamos a utilizar los parámetros.
Por ejemplo, podemos tener una función que nos dibuje algo allí donde está el mouse
o bién allí donde clicamos
Aquí la gracia está en que en ambos casos utilizamos exactamente la misma función:
void dibujaUnSputnik(int x_, int y_){
strokeWeight(3);
stroke(255);
fill(255,0,0);
line(x_-30,y_-30,x_+30,y_+30);
line(x_-30,y_+30,x_+30,y_-30);
ellipse(x_,y_,35,35);
}
es decir, la reutilizamos. La misma función exactamente en dos applets distintos. La diferencia está en el momento en que la función es invocada. En el primer ejemplo, en el DRAW, y en el segundo, en otra función de sistema: MOUSEPRESSED, que se ejecuta cuando se clica el mouse.
Pero aquí la función tiene una característica distinta a las del punto anterior. La función dibujaUnSputnik recibe parámetros. Concretamente recibe dos. Dos enteros. De aquí que al declarar la función no dejemos el paréntesis en blanco:
Lo que está dentro del paréntesis son pues los parámetros, que se reciben en forma de variable. Unas variables que hay que declarar como vemos, y que llamamos en este caso x_ e y_.
Los valores que se asignarán a dichas variables serán los de los parámetros que especifiquemos al asignar la función. Así,
Asignaría a x_ el valor 87 y a y_ el valor 349 en dicha función. En nuestros ejemplos, lo que se les asigna es otra variable, en este caso variable de sistema, pero que no deja de ser un entero: mouseX y mouseY.
3.- Retorno
Otra cosa que pueden hacer las funciones, y aquí, aunque puede parecer que la cosa se complica, es cuando las cosas se vuelven interesantes. Además de poder o no recibir parámetros, una funcion puede o no devolver (retornar) valores. Hasta ahora hemos visto funciones que nunca devuelven nada. Este tipo de funciones simplemente se invocan, con o si parámetros, si más.
¿Pero qué pasa si una función devuelve un valor? ¿A quién se lo devuelve y cómo lo gestionamos? Pues de hecho es bien sencillo. Cuando invocamos una función que devuelve un valor, hemos de asignar éste valor a una variable (o utilizarlo directamente). Es algo que de hecho hemos estado ya haciendo con random.
Por ejemplo, si tenemos una función llamada calculines que nos realiza los dificilísimos calculos de hacer la media entre dos valores, la asignaríamos a una variable llamada resultado:
int resultado; resultado = calculines(32,439);
Y la función en sí sería algo así:
int calculines(int a_, int b_){
int aRetornar;
aRetornar = (a_+b_)/2;
return aRetornar;
}
Otro aspecto muy importante ahora es la declaración de la función. Y aquí por fin cobrará sentido el famoso void: Cuando declaramos una función que devuelve un valor, debemos especificar el tipo de datos que devuelve al declararla. Así, una función que devuelve un entero se declararía por ejemplo así:
int dameUnEnteroBonito(){
//instrucciones
}
Y una que nos ha de devolver un float:
float dameUnFlotador(){
//instrucciones
}
Y, finalmente, hay que tener SIEMPRE, en una función que retorna algo, una instrucción de retorno al final. Dicha instrucción se llama return y va seguida de un valor que se retorna, valga la redundancia...
float dameUnFlotador(){
//instrucciones donde flotador es una variable del tipo float
return flotador;
}
Como siempre, mejor con ejemplos:
Uno sin posiciones ni velocidades... Podemos utilizar arrays, loops y funciones para hacer cosas como contar notas medias (de paso repasamos texto):
Notas I:
Notas II:
Y otro ejemplo: Imaginaros que tenemos dos equipos de porgramadores. Unos tienen que hacer un dibujo según lo rápido que se mueva el mouse. Los otros, contar los píxels blancos. Lo típico, vaya...
Pues con funciones cada equipo podría trabajar por separado y al final integrarlo todo en un solo sketch:
4.- Más ejemplos
No, no olvidaremos a las pelotitas, pero ahora podemos utilizar una función para hacer que lo que rebota no sea una pelota, sinó el rebicho. Además, mirando el código veréis como en funciones es cuestión de organización.
Y finalmente, otro ejemplo del uso de funciones y de paso introduciendo otras ideas de programación más interactiva.
Otro ejemplo del uso de funciones, y de paso de interacción:
5.- Práctica
Llegó el momento de hacer la práctica final con Processing, que presentaréis en dos semanas.
Por lo tanto se impone un ejercicio libre donde cada uno pueda experimentar con lo que ha aprendido durante estas siete sesiones introductorias más la de la semana siguiente si queréis.
----------------------------------------------------------------------------------------------------
-- Estos apuntes son el complemento de una clase al Máster de Artes Digitales de la UPF. No estan pues diseñados para consituir necesariamente un tutorial completo y coherente por si mismos --
© 2006-2010. Joan Soler-Adillon. Todos los derechos reservados.
-- La licencia CC que había en el tutorial queda anulada a efectos inmediatos en mayo de 2010. Los malos usos de ésta han llevado al autor a esta decisión --
-- Si utilizáis el tutorial para fines docentes, se os agradecerá que lo comuniquéis al autor, para poder listar aquí vuestra clase/asignatura --
-- Podéis contactar con el autor (joan [punto] soler [a] upf [punto] edu) para pedir permiso de cara a la utilización o reproducción parcial del tutorial. Nunca se os pedirá nada material a cambio, sino alguna pequeña contribución al mismo: Nuevos ejemplos, propuestas de mejora en alguna parte, o incluso mejor: Nuevas sesiones que cubran temas que el tutorial no explica: Vídeo, sonido, clases, etc.--