Palabras clave: Funciones, Argumentos, Parámetros.

Preguntas de repaso
  • ¿Cómo se escribe la función principal en Processing?

  • Si la variable a almacena el valor 1, ¿qué hará la instrucción a=a+1;?

  • ¿Qué es un tipo de dato?

  • ¿Qué significa y qué hace la instrucción boolean encontrado = false;? Dibújalo.

No sigas si no conoces las respuestas.

1. Funciones

En programación, una función es un grupo de instrucciones con un objetivo en particular y que se ejecuta al ser llamada desde otra función.

Las funciones deben tener un nombre único.

Cuando en una línea de programa se menciona a una función, se dice que se invoca o llama a dicha función. Una función puede invocarse múltiples veces e incluso llamarse a sí misma (en cuyo caso se habla de función recurrente).

Processing tiene muchas funciones. Destaca por su importancia la función setup() por ser la función principal.

2. Parámetros y Argumentos

Los parámetros de una función hacen referencia a los datos que son necesarios para poder ejecutar el grupo de instrucciones asociadas a dicha función.
Ejemplo 1. Cada función requiere de un número de parámetros
  • La función size() tiene dos parámetros, pues se requieren dos datos que representan el ancho y el alto de la ventana gráfica. Los dos parámetros son numéricos.

  • La función text() tienen 3 parámetros, pues se requiere uno que represente el texto a mostrar en la ventana gráficas y dos para indicar el punto de la ventana donde el texto se colocará.

Una función no necesita obligatoriamente de parámetros. Hay funciones que no los necesitan.

Ejemplo 2. Algunas funciones que no necesitan parámetros.

Algunas de las funciones disponibles en Processing y que no necesitan parámetros son: exit(), noFill(), noStroke(), noLoop(), etc

Cuando una función no tienen parámetros también se le suele llamar procedimiento.

Si una función requiere de parámetros, estos necesariamente responden a un tipo de dato.

Ejemplo 3. Cada parámetro responde a un tipo de dato
  • La función size() tiene dos parámetros numéricos y ambos son de tipo int

  • La función text() tienen 3 parámetros, uno es de tipo String y los otros dos son de tipo int.

Los argumentos son los valores concretos con los que se invoca a una función.

Si una función tiene un parámetro tendrás que suministrar un argumento, si tiene dos parametros tendrás que aportar 2 argumentos, …​ y así sucesivamente. Cuando se aportan tantos argumentos como parámetros pasan todas estas cosas:

  1. Cada uno de los parámetros de la función son variables locales en dicha función.

  2. El primer parámetro tiene asociado el primer argumento, el segundo parámetro tiene asociado el segundo argumentos, …​ y así sucesivamente.

  3. A cada parámetro (que es una variable local) se le asigna una copia del valor que almacena su correspondiente argumento.

Cuando una función asigna a un parámetro una copia del valor del argumentos, se dice que dicho argumento pasa por valor.
Ejemplo 4. Ejemplo de paso por valor

La función text() tienen 3 parámetros, el primero es de tipo String y los otros dos son de tipo int. Suponte que el primer parámetro se llama texto y los dos siguientes se llamann posX y posY.

Sin invocas a la función de esta forma text(saludo, x, 40); siendo saludo y x variables de tipo String e int, respectivamente entonces se produce lo siguiente:

  • texto guardará una copia de la cadena alfanumérica almacenada para saludo.

  • posX guardará una copia del valor almacenado en la variable x, y

  • posY guardará una copia del valor 40.

A efectos prácticos, es lo mismo que si hicieras:

String texto = saludo;
int posX = x;
int posY = 50;
Recuerda que un parámetro es un valor de entrada que espera una función y que un argumento es un valor (literal o variable) que suministras a la función.

3. Resultado / Retornos

Los resultado de una función hacen referencia al valor que devuelve dicha función. Los resultados también reciben el nombre de valores de retorno o de salida.
Ejemplo 5. Algunas funciones que retornan valores

En Processing existen muchas funciones que devuelven valores, como por ejemplo:

  • La función sin() devuelve un valor numérico real.

  • La función year() devuelve un valor numérico entero.

  • La función join() devuelve una cadena de caracteres (String).

Una función no necesita obligatoriamente devolver un valor. Hay funciones para las que no tiene sentido.

Ejemplo 6. Algunas funciones que no retornan valores

Algunas de las funciones disponibles en Processing y que no retornan valores son: setup(), println(), noStroke(), mousePressed(), etc

Si una función retornara algún valor, éste necesariamente responde a un tipo de dato y puede guardarse en una variable del mismo tipo.

Ejemplo 7. El valor de retorno responde a un tipo de dato
  • La función sin() devuelve un dato de tipo float y esto es correcto:

float seno = sin(PI);  // sin() tiene un parámetro float.
  • La función year() devuelve un dato de tipo int y esto es correcto:

int agno = year();  // year() no tiene parámetros.
  • La función join() devuelve un dato de tipo String y esto es correcto:

String resultados = join("2.5", " euros"); // join() tiene dos parámetros de tipo String
Recuerda
No es lo mismo retornar (o devolver o calcular) valores que mostrar valores.

La función println() muestra valores en la consola gráfica, pero no significa que retorne un valor. Es decir, la función prinln() no retorna un valor que pueda ser guardado en una variable.

Una función no está obligada a retornar un valor. Puede retornar a lo más uno; es decir: o uno o ninguno.

4. ¿Cómo construir tus propias funciones?

Para construir una función tienes que especificar cada una de las partes que la componen, y éstas son las siguientes:

  1. La declaración de la función. Presenta el patrón:

    <td de retorno> nombre_de_la_función (<td 1> <nombre parámetro1>, <td 2> <nombre parámetro1>, …​)

    que consta de:

    1. El tipo de dato del valor que retornará, si devuelve algún valor. Si no devolviera valores se pondrá la palabra void.

    2. El nombre de la función. Se sigue el mismo criterio de escritura de las variables.

    3. La lista de parámetros. Un parámetro se especifica igual que la declaración de una variable; esto es, deberá indicarse el tipo de dato del parámetro seguido de su identificador.

  2. La definición o cuerpo de la función.

    • Consta de la secuencia de instrucciones que se deseen agrupadas entre las llaves { y }.

    • En el cuerpo se deberán de utilizar todos los identificadores de los parámetros. Si alguno no se utilizara es porque no es necesario y deberá suprimirse de la definición.

    • Si la función retorna algún valor se deberá de usar la instrucción return <valor>;.

Parámetro es el nombre que recibe una de las variables que aparecen en la declaración de la función. Argumento es el nombre que recibe uno de los valores que es suministrado a la función cuando es invocada. Un argumento puede ser una valor literal, un valor calculable o una variable.

5. ¿Cómo usar tus propias funciones?

Se utilizan exáctamente igual que las funciones del lenguaje de programación.

Para invocar una función construida por ti, en una línea de tu programa deberás poner el nombre de tu función seguido de los argumentos que consideres, que serán tantos como parámetros hayas declarado en tu función. El primer argumento deberá ser del mimo tipo que el primer parámetro, el segundo argumento deberá ser del mimo tipo que el segundo parámetro, …​ y así sucesivamente.

Si tu función retornara algún valor, podrás recuperar el valor guardandolo en una varible del mismo tipo que el valor devuelto.

6. Tipos de Variables

Hagamos un resumen de los tipos de variables que podemos encontrarnos en un programa y relacionemoslos con otros conceptos importantes.

  • Una variable es una porción de memoria donde se almacenan valores y que se identifica con un nombre.

  • Podemos definir cuantas variables deseemos siempre y cuando no coincidan en nombre con las variables predefinidas por el lenguaje de programación.

  • Una variable es reconocida en un bloque de código si al mencionar a la variable en dicho código se puede recuperar su valor. O si se prefiere, cuando se le puede asignar un valor.

    Recuerda que un bloque de código es todo lo que va entre llaves {}.
  • Se llama ámbito de una variable a los bloques de código donde una variable es reconocida.

  • Una variable es una variable global cuando el ámbito de la variable son todos los bloques de código.

  • Una variable es una variable local cuando no es una variable global.

  • Una variables local solo es reconcida en el bloque donde fue definida y en todos los bloques que estén contenidos en aquel. Por tanto, es algo local respecto a todo el programa: está localizada solo en algunos bloques del programa.

  • En abuso de lenguaje, se puede uno referir a una variable local como una variables global respecto de los bloques donde es reconocida.

  • Un parámetro es una variable local: solo es reconocido en el cuerpo de la función.

  • Un parámetro siempre se inicializa con el valor dado por su argumento.

  • Si el argumento de una función es una variable, dicha variable NO es una variable local de la función.

  • Un parámetro siempre copia el valor de su argumento. Es decir, si el argumento de una función es una variable, el valor del argumento se asigna al parámetro.

Ejemplo 8. Variables locales, globales, argumentos y parámetros

Con el siguiente código repasamos todos los conceptos indicados anteriormente.

float x;

void draw() {
    float w = 0.01;

    background(0);
    dibujaCirculo(x, height/2);
    x += w;
}

void dibujaCirculo(int posX, int posY) {
    float w = 10;
    ellipse(posX, posY, w, w); // Dibuja un círculo
}

void keyPressed() {
    float w = width/2;

    x = random(0, w);
}
  • Son variables en el programa: x, w (hay tres), height y width.

  • Las variables x y w se definen por el programador. Las variables height y width son variables del lenguaje de programación.

  • Las variables x, height y width son variables globales y por tanto su ámbito es todo el programa (se reconocen en todos los bloques).

    • Observa la variable x. Está declarado "fuera" de todos los bloques. Ese es el motivo por el que esa variable es reconocida por todos ellos.

  • Las siguientes variables son locales:

    • La variable w que aparece draw() es local y solo es reconocida en draw().

    • La variable w que aparece dibujaCirculo() es local y solo es reconocida en dibujaCirculo().

    • La variable w que aparece keyPressed() es local y solo es reconocida en keyPressed().

    • La variables posX y posY que aparecen en dibujaCirculo() son parámetros y por tanto son variables locales que solo son reconocidas en dibujaCirculo().

  • La variables posX y posY que aparecen en dibujaCirculo() son locales y solo son reconocidas en dibujaCirculo().

  • La variables posX y posY que aparecen en dibujaCirculo() toman su primer valor copiando los valores de la variable global x y del resultado de la operación aritmética height/2, respectivamente.

7. Ejemplos de Funciones

7.1. Un ejemplo sin parámetros y sin valor de retorno

Se quiere construir una función que siempre dibuje los ejes cartesianos en color rojo y en el centro de la ventana gráfica. Atendiendo a cada una de las dos partes que se necesitan establecer (declaración y definición de la función), tenemos:

  1. La declaración de la función será:

    void muestraEjesCartesianos()

    pues

    1. no queremos que retorne ningún valor,

    2. el nombre ha de ser significativo y se escribe cumpliendo las normas de minúsculas y mayúsculas.

    3. no ponemos parámetros de entradas pues la función no depende de nada.

  2. La definición de la función que deberá inidicarse entre las llaves { y } es:

    stroke(255, 0, 0); // Color rojo
    line (0,height/2, width, height/2); // Línea horizontal
    line (width/2, 0, width/2, height); // Línea vertical

Escribiendo todo junto, nuestra función, definida por nosotros, es:

1 2 3 4 5
void muestraEjesCartesianos() { stroke(255, 0, 0); // Color rojo line (0,height/2, width, height/2); // Línea horizontal line (width/2, 0, width/2, height); // Línea vertical }

Si la usáramos en un programa, deberá de ser invocada en alguna otra función. Por ejemplo, un programa correcto en el que nuestra función es utilizada por nuestra función principal es

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/** Curso 2015-16, ISCyP Ejemplo de uso de una función que ni requiere parámetros/argumentos ni valor de retorno. Mostrar el eje de coordendas centrado en la patalla gráfica y en color rojo. **/ // Construimos una función que muestra lo que se solicita // Parámetros de entrada: ninguno. No se necesitan. // Valor de retorno: void. No se necesita. void muestraEjesCartesianos() { stroke(255, 0, 0); // Color rojo line (0, height/2, width, height/2); // Línea horizontal line (width/2, 0, width/2, height); // Línea vertical } // Función Principal del Sketch void setup() { size(600, 400); // Tamaño de la ventana gráfica muestraEjesCartesianos(); // Invocamos a nuestra función }

7.2. Un ejemplo con parámetros y sin valor de retorno

Imagina que partiendo del ejemplo anterior queremos dibujar el origen de los ejes en el pixel que se considere.

  1. Para ello deberemos cambiar la declaración de la función para que contemple las coordenadas del pixel:

    void muestraEjesCartesianos(int x, int y)
  2. Y en la definición de la función deberemos de utilizar dichos parámetros:

    stroke(255, 0, 0);
    line (0,y, width, y);
    line (x, 0, x, height);

Escribiendo todo junto (declarción y definición), nuestra función queda:

1 2 3 4 5
void muestraEjesCartesianos(int x, int y) stroke(255, 0, 0); line (0,y, width, y); line (x, 0, x, height); }

Haz un programa cuyo programa principal invoque a esta nueva función muestraEjesCartesianos().

7.3. Un ejemplo con parámetros y con valor de retorno

Ahora, partiendo del último ejemplo supón que queremos retornar el ángulo que forma el punto (x,y) del argumento con el centro del origen de la pantalla gráfica de Processing.

  1. Para ello deberemos cambiar la declaración de la función para que contemple la devolución de un valor (real):

    float muestraEjesCartesianos(int x, int y)
  2. Y en la definición de la función debemos de añadir la correspondiente función return:

    stroke(255, 0, 0);
    line (0,y, width, y);
    line (x, 0, x, height);
    return atan2(y,x);

Escribiendo todo junto, nuestra función, definida por nosotros, es:

1 2 3 4 5 6
float muestraEjesCartesianos(int x, int y) stroke(255, 0, 0); line (0,y, width, y); line (x, 0, x, height); return atan2(y,x); }

Haz un programa cuyo programa principal invoque a esta nueva función muestraEjesCartesianos() imprimiendo el resultado en la coordenada (10,10) de la pantalla gráfica.

8. Repaso

  • La declaración presenta la forma:

    <td de retorno> nombre_de_la_función (<td 1> <nombre parámetro1>, <td 2> <nombre parámetro1>, ...)

    donde td son las iniciales de tipo de dato.

    • Si no devolviera valores, <td de retorno> será void.

    • Si no tuviera parámetros, no habrá contenidos entre ( y ). Parámetro es el nombre que recibe una de las variables que aparecen en la declaración de la función.

  • La definición presenta la forma:

    {
       Instrucciones que quieras
    }
    • Si la función retornara algún valor, la última instrucción tiene que ser return <valor>;, donde el valor devuelto deberá ser del mismo tipo de dato que <td de retorno>.

  • Invocar a un función consiste en "mencionar" a la función en alguna línea del programa indicando entre paréntesis tantos valores como parámetros tenga la función.

  • Argumento es el nombre que recibe uno de los valores que es suministrado a la función cuando es invocada. Un argumento puede ser una valor literal, un valor calculable o una variable.

  • Los parámetros actúan como variables locales de la función.

  • En una invocación, los parámetros almacenan una copia del valor suministrado por su correspondiente argumento.