Palabras clave: Instrucciones simples, Funciones.

Preguntas de repaso
  • ¿Qué es un algoritmo?

  • ¿Cuáles son las 4 consideraciones que debes tener para diseñar un algoritmo?

  • ¿Qué es un programa?

  • ¿Qué es un enlazador (linker)?

No sigas si no conoces las respuestas.

1. Instrucciones simples

Una instrucción simple es aquella que finaliza en punto y coma y puede ser:

INSTRUCCIONES SIMPLES
  • Una declaración y uso de variables; p.e., float x; o y=x+2;.

  • Una expresión con operadores; p.e., 2+5; o 3/5.2.

  • Una llamada a una función; p.e., print("hola"); o sin(1.5);.

  • Una instrucción compuesta por varias instrucciones simples; p.e., println(cos(2.4)));.

En esta lectura veremos los tres últimos tipos de instrucciones simples.

2. Funciones

Una función es una orden que se le da al ordenador expresada en un lenguaje de programación. Le dices "haz esto", "haz aquello", …​ Por ejemplo, puedes decirle "haz un círculo", "haz que se muestre un mensaje", "haz un sonido", …​ Hay órdenes que son sencillas en el sentido de que en el lenguaje de programación se dispone de instrucciones que las realizan directamente. Hay otras órdenes que son muy complejas y tendremos que "explicar" al lenguaje de programación cómo debe de hacerla expresando esa orden compleja como una secuencia de órdenes simples que el lenguaje sí es capaz de realizar.

Una función representa a una o varias instrucciones que permiten realizar una acción simple o compleja y dicha acción se identifican con un nombre único.

Si dicho nombre aparece en una línea del programa con la intención de que realice una acción se dice que el programa invoca a la función y si se ejecutan (realizan) todas las instrucciones de la función se dice que se ha ejecutado la función.

La invocación a una función se reconoce porque aparecen los símbolo ( y ) - propios de toda función - y el punto y coma ; - propio de toda instrucción.

Ejemplo 1. Concepto de función

Imagina que en un lenguaje de programación ficticio le pedimos al ordenador que realice las siguientes instrucciones simples (que es capaz de realizar directamente) consistentes en mostrar un mensaje para que el usuario introduzca una orden por teclado:

muestraMensaje "Hola humano";
muestraMensaje "¿Qué haces?";
muestraMensaje "Estoy esperando una instrucción ....";

Este programa consta de 3 líneas de código y en cada una de ellas se realiza la instrucción muestraMensaje.

En nuestro lenguaje ficticio podríamos agrupar las 3 instrucciones e identificarlas con el nombre que consideremos más adecuado, digamos, por ejemplo, avisaAlUsuario(). El modo en que se agrupan las instrucciones en una función depende del lenguaje. En nuestro lenguaje ficticio se agruparán de esta forma:

avisaAlUsuario() {
    muestraMensaje "Hola humano";
    muestraMensaje "¿Qué haces?";
    muestraMensaje "Estoy esperando una instrucción ....";
}

Con los símbolos () indicamos que creamos una función y con los símbolos {} indicamos cuáles son las instrucciones que agrupa.

Así, de acuerdo a nuestro lenguaje ficticio, la ejecución de las tres instrucciones muestraMensaje son equivalentes a la ejecución de la función avisaAlUsuario(); y podemos entonces sustituir el primer programa, formado por 3 líneas de código fuente, por este otro, formado por una sola línea:

avisaAlUsuario();

De este último listado también podemos decir que el programa invoca a la función avisaAlUsuario() pues aparece el nombre de la función con la intención de dar una orden - pues aparecen los símbolo (, ) y ;. La orden consiste en pedir que se ejecute la función avisaAlUsuario, o lo que es lo mismo, en ejecutar 3 veces la instrucción muestraMensaje con los textos indicados en el primer listado.

En el ejemplo anterior nos hemos inventado tanto las instrucciones como la función en un lenguaje ficticio, sin embargo esto en la práctica no lo podemos hacer. No podemos inventarnos las instrucciones a nuestro antojo. Hemos de utilizar las instrucciones propias del lenguaje de programación que vayamos a utilizar.

Processing dispone de muchas funciones que nos ayudan a dar ordenes al ordenador. Tendrás que memorizar las más importantes. Además, como se verá en una sesión posterior, también podrás construir tus propias funciones con los nombres que consideres más adecuados de forma análoga a como se ha indicado en el ejemplo anterior.

Puedes visualizar las funciones de Processing

Abre la página de referencia del lenguaje Processing. Observa que las funciones se caracterizan porque tiene paréntesis () después de un nombre. ¿Cuántas funciones eres capaz de ver a golpe de vista?

3. Función principal

Todos los lenguajes de programación tienen muchas funciones y algunos de ellos requiere de una función principal.

Una función principal es aquella que es invocada siempre como la primera instrucción del programa.

En general, para usar cualquier función del lenguaje de programación deberás de escribir la correspondiente instrucción invocando a dicha función. Pero hay contadas excepciones. Una de ellas es que no tendrás que escribir en ninguna parte de tu programa la instrucción que invoque a la función principal. El lenguaje de programación lo hará por ti: buscará la función principal y si existe ejecutará las líneas de código que aparezcan en ella.

La función principal de Processing se llama setup() y siempre se pone así:

void setup() {
  Instrucciones que tú quieras de Processing.
}

Processing permite, opcionalmente, utilizar una función principal. Así, cuando tú escribas un programa que tenga un código similar al anterior, le estás indicando a Processing que hay una función principal y, como tal, lo primero que hará Processing serán invocar a la función principal setup() lo que es equivalente a ejecutar las instrucciones que se indiquen entre { y }.

Todo lo que se indica entre las llaves { y } recibe el nombre de bloque, cuerpo o definición de la función.

Como acabamos de decir, la función setup() es una función que puedes o no escribir. ¿Cuándo se debe entonces poner obligatoriamente esta función en un programa de Processing? Pues cuando se cumpla alguna de las dos condiciones siguientes:

  • Si hay funciones que hayas construido tú.

  • Si vas a usar la función draw() de Processing.

Estos dos aspectos los veremos en sesiones posteriores.

El significado de void indica que la función no retorna ningún resultado. Este aspecto se explicará con detenimiento más adelante.

4. Funciones de impresión

Los ordenadores son sistemas electrónicos que trabajan con información para dar resultados referentes a esa información. Processing puede mostrar los resultados que le pidamos en la pantalla ya sea en la ventana gráfica o en la consola de texto.

Para mostrar información en la consola de texto se utilizan las instrucciones print y println.

Realiza los siguientes pasos:

  1. En el PDE abre la página principal de las referencias de Processing. Alternativamente visita esta página https://www.processing.org/reference/.

  2. Busca las funciones print y println. Lee solo las 3 primeras líneas del apartado Description.

    ¿Qué diferencia hay entre ambas instrucciones?

  3. Escribe el siguiente código en la ventana de edición de Processing.

    Listado 1. Un programa que imprime números
    1 2 3 4
    void setup() { // Indicamos que la función principal consta de: print(4); // - Una instrucción: print() println(4); // - Otra instrucción: println() }

    Un comentario en un programa es un texto que no es procesado por el lenguaje de programación y que sirve para explicar líneas del programa.

    En Processing todo lo que aparezca después de dos caracteres / consecutivos se considera un comentario. Todo lo que se escriba a continuación de // será ignorado por Processing y no será procesado.

    Run
  4. Busca en la barra de herramientas el botón de ejecución (icono triángulo de la derecha) y haz click sobre él.

  5. Mira el mensaje de la consola de texto. Debe de aparecer 44. ¿Por qué crees que aparece eso?

    A veces te encontrarás el siguiente icono. Púlsalo. Se mostrará una ventana con una ejecución análoga al PDE. Tendrá su propia "ventana gráfica" y su "consola de texto"

    Stop
  6. En el PDE pulsa el botón de Stop (icono cuadrado de la derecha) para cerrar la ventana gráfica y parar la ejecución del programa.

  7. Ahora modifica el código en la ventana de edición de Processing para que se muestre un cuatro, 4, debajo del otro cuatro, 4. Consulta de nuevo la descripción de print o println si lo vieses necesario.

Pero println() no solo muestra números en la consola de texto. También puedes mostrar mensajes de texto como verás en el siguiente ejercicio.

  1. Escribe el siguiente código en la ventana de edición de Processing.

    Listado 2. Un programa con una única línea para imprimir un texto
    1
    println("Hola\n\t ¿cómo estás R2P2?");
    Run
  2. A continuación pulsa el botón "run", mira el contenido de la consola e intenta explicar qué es lo que ha pasado.

Los mensajes de texto se llaman secuencias de caracteres. Una secuencia de caracteres es aquello que empieza y termina con comillas dobles, ", y está formado por una sucesión de símbolos que pueden representar números, letras o caracteres de escape. Las comillas dobles no forman parte del texto que se muestra - solo sirven para delimitar dónde empieza y dónde termina la secuencia de caracteres. Los caracteres de escape son aquellos símbolos que pueden dar órdenes al ordenador y no son visibles cuando se muestra la secuencia de caracteres. En el ejercicio se muestran dos caracteres de escape: el \n y el \t, que sirven para empezar una línea nueva e indentar (o tabular) el texto respectivamente.

Escribe el código necesario para generar la salida que se muestra teniendo en cuenta las restricciones que se indican:

  1. Usa exactamente tres instrucciones println().

  2. Usa una única instrucción print().

Consigue esta salida en la consola de texto
*****
 ***
  *

A veces te encontrarás el siguiente icono. Púlsalo cuando hayas resuelto el ejercicio.

5. Argumentos

Hemos indicado que una función es una orden que se le da a un lenguaje de programación. Las órdenes deben de ser muy concretas.

Un concepto que está asociado a las funciones es el de argumento.

Un argumento es un valor que se le suministra a una función.

Según hemos visto en las dos sesiones anteriores a la función println() le hemos suministrado tanto un número, el 4, como una cadena alfanumérica, la cadena "Hola\n\t ¿cómo estás R2P2?". Según la definición de argumento, tanto el 4 como la cadena son argumentos de la función println().

Cuando un argumento es un número se dice que es un argumento numérico, y si el argumento es una cadena alfanumérica se dice que es un argumento alfanumérico o de tipo String.

println() es un ejemplo de función con un argumento. Hay funciones que pueden exigir 2, 3, …​ o más argumentos como veremos en breve. Por contra, hay funciones que no necesitan argumentos.

La función principal setup(), que es la primera en ejecutarse si está presente, es una de esas funciones a las que no se le puede suministrar argumentos.

6. Expresiones

Los argumentos que hemos suministrado a la función println() son valores literales.

Un valor es literal si representa a un valor fijo en el código del programa.
Ejemplo 2. Valores Literales

En los siguientes dos programas:

1 2 3 4
void setup() { // Indicamos que la función principal consta de: print(4); // - Una instrucción: print() println(4); // - Otra instrucción: println() }
1
println("Hola\n\t ¿cómo estás R2P2?"); // Este programa no tiene función principal

tanto el 4 como "Hola\n\t ¿cómo estás R2P2?" son valores literales.

Frente a los valores literales están los valores calculables.

Un valor es calculable si viene determinado por una expresión, la cual puede ser o numérica o alfanumérica.

En esta lectura nos centraremos sólamente en las expresiones numéricas.

Una expresión numérica responde a una expresión matemática pero escrita en un lenguaje de programación.

Por tanto, en una expresión numérica aparecen operadores, operandos y funciones "matemáticas" entendiendo aquí como función "matemática" a cualquier función del lenguaje que nos dé como resultado un número.

En las dos siguientes tablas te muestro los operadores aritméticos usuales:

Operadores aritméticos con números enteros
Nombre Operador Ejemplo Resultado

Suma

+

4+6

10

Resta

-

4-6

-2

Multiplicación

*

4*6

24

División entera

/

4/6

0

Resto o módulo

%

4%6

4

Operadores aritméticos con números reales
Nombre Operador Ejemplo Resultado

Suma

+

4.0+6.0

10.0

Resta

-

4.0-6.0

-2.0

Multiplicación

*

4.0*6.0

24.0

División Real

/

4.0/6.0

0.666667

Resto o módulo

%

4%6

4.0

Observa que:

  • Las operaciones con reales se diferencian de las operaciones con naturales en el punto decimal que aparece en los operandos.

  • El operador % devuelve siempre el resto de la división entera, independientemente de si los operandos son enteros o reales.

  • La división entera y la división real solo se pueden diferenciar por los operandos. Si los dos operandos son naturales, entonces / será una división entera; pero si uno de los operandos es real (tiene un punto decimal), entonces la división será real.

En la siguiente tabla se muestra algunas de las funciones matemáticas más usuales. Todas ellas requieren de un único argumento numérico (que puede ser natural o real) y todas nos devuelven un resultado numérico real.

Algunas funciones matemáticas usuales
Processing Significado Processing Significado

abs(x)

Valor absoluto

ceil(x)

Entero más cercano superior

round(x)

Redondeo de x

floor(x)

Entero más cercano inferior

exp(x)

Exponencial en base e

log(x)

Logaritmo en base e

pow(x,y)

Potencia y en base x

sqrt(x)

Raíz cuadrada

Algunas funciones trigonométricas
Processing Significado Processing Significado

sin(x)

Seno de x radianes.

asin(x)

Arcoseno

cos(x)

Coseno de x radianes.

acos(x)

Arcocoseno

tan(x)

Tangente de x radianes.

atan2(y,x)

Arcotangente del vector con origen en (0,0) y extremo en (x,y)

radians(x)

Convierte grados sexagesimales a radianes

degrees(x)

Convierte radianes a grados sexagesimales

7. Funciones anidadas

En programación puedes calcular una expresión a partir de un conjunto de valores y entonces usar el resultado del cálculo realizado como un valor a utilizar en una segunda expresión. Se puede entonces usar el valor obtenido en esta segunda expresión como un valor a utilizar en una tercera expresión. De nuevo se puede usar el valor solución de esta tercera expresión en una cuarta expresión, y así repetir el procedimiento cuantas veces lo consideres pertinente para resolver tu problema.

Lo indicado es totalmente equivalente a este otro proceso. Puedes usar un argumento para que una función calcule un valor y entonces usar ese valor como argumento en una segunda función. Se puede utilizar el valor retornado por la segunda función como argumento para una tercera función, y así sucesivamente repetir el proceso cuantas veces necesites.

Esto no es nuevo para ti. En matemáticas lo llamas composición de funciones.

La composición matemática de \(f(x)=x^2+3\), \(g(x)=e^x\) y \(h(x)=sen(x)\) es la función: \((h\circ g\circ f)(x)=sen(e^{x^2+3})\)

En Processing, la expresión es sin(exp(sq(x)+3)).

La idea de la composición de funciones matemáticas recibe el nombre de funciones anidadas en el contexto de la programación.

En un lenguaje de programación no puedes componer las funciones como se te ocurran. Tienes que tener cuidado: el valor devuelto por una función deber ser una argumento aceptado por la siguiente función.

Por ejemplo, como la función println() admite argumentos numéricos, en esta función se puede usar como argumento una expresión matemática que puede ser a su vez una composición de funciones matemáticas.

Ejemplo 3. Funciones anidadas

El siguiente programa muestra un ejemplo de anidamiento de funciones:

println(sin(3.14)/cos(3.14));

Realiza las siguientes acciones:

  1. Calcula sin(3.14), que es -0.0015.

  2. Calcula cos(3.14), que es 0.9999.

  3. Calcula el cociente -0.0015/0.9999, que es -0.0016.

  4. Imprime el resultado -0.0016 en la consola de texto.

Observa que las operaciones se realizan de "dentro" hacia "afuera", como harías en una composición de funciones matemáticas.

Escribe la instrucción que permite imprimir el resultado de la siguiente operación: \(sen(\pi+\sqrt{e^{-3}+\pi^2}+4)\)

8. Precedencia de operadores y funciones

Estrictamente hablando, todas las expresiones matemáticas tienen muchos paréntesis aunque no se escriban. Por ejemplo, la expresión correcta de \(2\times 3+ 12.0:6\) es \(((2\times 3)+(12.0:6))\); pero en la práctica no solemos usar la segunda expresión sino la primera. La primera es más simple y a pesar de que no tiene todos los paréntesis sabemos el orden en el que los cálculos se deben de hacer: las multiplicaciones y divisiones preceden a las sumas y restas.

Este mismo principio también lo aplican los lenguajes de programación. Más concretamente, el orden de precedencia es el que a continuación se indica:

Orden de Precedencia

El orden de prioridad en una expresión numérica es:

  1. Paréntesis: ( )

    La expresión que se encuentre dentro de un paréntesis será la primera en ser calculada.

  2. Funciones matemáticas.

  3. Operadores relacionados con los productos y divisiones: *, /, %

  4. Suma y resta: +. -

    Las operaciones aditivas serán las últimas en ser aplicadas.

En el caso de que tener dos operadores que tengan la misma prioridad se realizará el operador que esté situado más a la izquierda.

Ejemplo 4. Ejemplo de operadores con la misma prioridad

En la expresión numérica \(6:2\times 3\), el operador de división y de multiplicación tienen la misma prioridad. ¿Cuál se hace antes? ¿la división o la multiplicación? En caso de empate siempre se asocia por la izquierda, por lo que la expresión real es \((6:2)\times 3\), cuyo resultado es 9.

Imprime el resultado de las siguiente operación: \(\displaystyle\frac{\displaystyle\frac{12+3}{4}\times 2}{8 - (4+ \frac{1}{3})}\)

Utiliza la menor cantidad de paréntesis posibles.

9. Comentarios

No todo lo que aparece en un programa son instrucciones. A veces, entre las instrucciones aparecen comentarios. Un comentario es un texto que aparece entre el código del programa cuyo contenido explica, normalmente en lenguaje natural, qué es lo que realizan las instrucciones a las que hace referencia.

Los comentarios son esenciales. Se estima que en grandes programas donde el código es muy complejo más de 2/3 de las líneas corresponden a comentarios. Quizás aplicar esta proporción a los programas que vamos a realizar sea un poco excesivo, pero pone de relieve la importancia de los comentarios.

Los comentarios no solo te ayudarán a aclarar qué quieres que hagan las instrucciones sucesivas, sino que además pemitirá explicar mejor a tus profesores qué es lo que estás haciendo con esas instrucciones.

El código se puede comentar de dos formas:

Comentario en línea

Se presenta en la misma línea donde aparecen las instrucciones que se quieren comentar. El comentario empieza escribiendo los caracteres // y no puede ocupar más de una línea. Por ejemplo:

println (2+2); // Imprime la suma 2+2

Todo lo que aparezca a continuación de los caracteres // incluidos ellos mismo será ignorado y no será procesado.

Comentario en párrafos

Se suele presentar antes del grupo de instrucciones que se quieren comentar y puede ocupar varias líneas. El comentario empieza en un línea con los caracteres /*, en otra línea posterior finaliza con los caracteres */. Las dos líneas y todo lo que se escriba en las líneas intermedias se considerarán comentarios y por lo tanto no será procesado (será ignorado por Processing). Por ejemplo:

/*
  Imprime la suma 2+2
*/
println (2+2);

10. Repasa y memoriza

  • En este documento hemos introducido las siguientes instrucciones simples: Una expresión con operadores, una llamada a una función, una instrucción compuesta por funciones anidadas.

  • println(4); ¡es una instrucción! Se reconoce porque termina en punto y coma. Esta instrucción se llama println.

  • Además, println(4); ¡es una función! porque después del nombre, que es println, se abre un paréntesis '(' y se cierra el paréntesis ')' justo antes del punto y coma. Todas las funciones tienen apertura de paréntesis después de su nombre y cierre de paréntesis antes del punto y coma.

  • Lo que se indica entre ( y ) recibe el nombre de argumento si hay uno, o de argumentos si hay más de uno. Hay funciones que no requieren de argumento alguno.

  • La función print() y println() puede tener un argumento numérico o alfanumérico (una cadena de caracteres).

  • Los argumentos también pueden ser el resultado de una expresión. Hay varios tipos de expresiones.

  • Una expresión numérica es una expresión matemática y como tal puede contener una o varias composiciones de funciones.

  • En una expresión numérica pueden aparecer operadores y/o funciones. Memoriza todas los operadores y las funciones matemáticas usuales.

  • Cuando una función aparece como argumento de otra función se dice que la primera está anidada en la segunda.

  • Cuando se evalúan una expresión numérica hay que tener en cuenta el orden de prioridad de operadores y funciones. Es fundamental memorizar el orden de precedencia.

  • La función principal de Processing se llama setup() y de aparecer será la primera función que se ejecute. Es una función que no tiene argumentos.

  • En todos los programas se deben de poner comentarios. Son obligatorios y fundamentales. Cuantos más mejor.