Functions
Functions
Functions
Revisión 2.0.0
2023-05-29
Tabla de contenidos
1. Introducción a Funciones ........................................................................ 1
1.1. Especificación Matemática ........................................................... 1
1.2. Implementación en C++ ............................................................... 1
1.3. Aplicación o Uso de la Función .................................................... 2
1.4. Estructura del Programa en C++ .................................................. 2
1.5. Proceso de Desarrollo ................................................................. 4
1.6. Conclusiones .............................................................................. 4
2. Funciones y Campos Escalares .............................................................. 7
2.1. Funciones de Escalares (1→1) .................................................... 7
2.1.1. Constante ........................................................................ 7
2.1.2. Identidad ........................................................................ 10
2.1.3. Sucesor .......................................................................... 10
2.1.4. Negación ........................................................................ 11
2.1.5. Twice (Dos Veces) .......................................................... 11
2.2. Funciones Partidas (Piecewise) .................................................. 11
2.2.1. Absoluto ......................................................................... 12
2.2.2. Step ............................................................................... 13
+
2.3. Funciones de Varias Variables — Campo Escalar: 2 →1 ............... 14
2.3.1. Promedio ....................................................................... 14
2.3.2. Máximo .......................................................................... 15
3. Funciones Sin Datos ni Resultados y Efecto de Lado ............................. 17
3.1. Dominio Vacío: Funciones sin Datos (0→1) ................................. 17
3.1.1. Constante sin Parámetros ............................................... 17
3.1.2. Solicitar Nombre ............................................................. 18
3.2. Transparencia Referencial y Efecto de Lado ................................ 19
+
3.3. Imagen Vacía: Funciones sin Resultados (0 →0) ......................... 19
3.3.1. Saludos .......................................................................... 20
3.3.2. Mostrar Adición de Dos Números Solicitados .................... 21
4. Recursividad en Funciones Puras ......................................................... 25
4.1. Sumatoria de los Primeros n Naturales ....................................... 25
5. Rol de los Parámetros: In, Out, e InOut ................................................. 27
5.1. Parámetro Out .......................................................................... 28
+
6. Funciones y Campos Vectoriales (0⁺→2 ) ............................................... 29
7. Pasaje de Argumentos ......................................................................... 31
iii
Funciones
8. Changelog ........................................................................................... 33
Bibliografía ............................................................................................... 35
iv
1
Introducción a Funciones
relaciona: .
2. Luego, la fórmula que define la relación:
double f(double);
double f(double x){ return 2*x + 1; }
1
Aplicación o Uso de la Función
/* f
[asciimath_]
++++
f:RR->RR
2
Estructura del Programa en C++
//
f(x)=2x+1
++++
f(3)=2*3+1=7
JMS
2018 */
#include <cassert>
#include <iostream>
double f(double);
int main(){
std::cout << f(3);
assert( f(3) == 2*3+1 );
assert( 2*3+1 == 7 );
}
El ejemplo usa declaraciones para eso, así vemos que la declaración está antes
de la invocación, en este caso, antes de main; mientras que la definición se ubica
debajo de main.
3
Proceso de Desarrollo
Por eso, usamos el estilo del C++ idiomático: primero prototipos, seguido de la
definición de main, seguido por la definición de las funciones.
Este proceso tiene como objetivo lograr una implementación de una función a
partir de una especificación matemática. Aunque usamos C++, este proceso es
aplicable a cualqueir lenguaje de programación compilado.
1. Especificación matemática.
2. Diseño de casos de prueba.
3. Codificación de las ecuaciones o assert (aseveraciones) en C++ que invoca
la función según los casos de prueba diseñados. Intentar compilar, el error
principal debe ser que la función no está declarada.
4. Declaración del prototipo. Debe haber concordancia entre las pruebas y el
pruebas y el prototipo. Intentar compilar, si hay concordancia, el error principal
debe ser que la función no está definida.
5. Definición de la función. Por último, y debajo de la función main codificar la
definición de la función que implementa el método de cálculo.
6. Compilar. Si hay error revisar los pasos anteriores.
7. Ejecutar. El programa debería finalizar sin mensajes, si hubo algún mensaje
de error es porque las aseveraciones fallaron, lo cual estamos ante la
presencia de un bug. Debemos revisar si hay concordancia entre la
especificación matemática, las pruebas, y la implementación en C++.
1.6. Conclusiones
Matemática C++
Relación: Dominio, Codominio Prototipo: tipo de la función, nombre,
y tipo de los parámetros.
4
Conclusiones
Matemática C++
double f(double);
assert( f(3) == 7 );
Fórmula Definición
1. Especificar.
2. Escribir las pruebas con assert.
3. Implementar.
4. Compilar, ejecutar, y evaluar resultados.
• Funciones escalares.
• Funciones partidas.
• Funciones de varias variables.
5
6
2
Funciones y Campos Escalares
Estas son funciones que dado un valor generan otro, son funciones de una sola
variable.
2.1.1. Constante
#include <cassert>
#include <iostream>
int y(int);
int main(){
std::cout << y(-9);
assert( 42 == y(1) );
}
7
Constante
8
Constante
9
Identidad
2.1.2. Identidad
#include <cassert>
#include <iostream>
int Id(int);
int main(){
std::cout << Id(42);
assert( 7 == Id(7) );
}
2.1.3. Sucesor
A partir de este ejemplo, vamos a incluir solo los puntos más importantes del
desarrollo de cada función:
1. Definición matemática.
2. Prototipo.
3. Pruebas.
4. Implementación.
int Suc(int);
10
Negación
2.1.4. Negación
int Neg(int);
assert( -7 == Neg( 7) );
assert( 0 == Neg( 0) );
assert( 42 == Neg(-42) );
int Twice(int);
11
Absoluto
Selección
Otra alternativa para implementar las funciones partidas es mediante
control de flujo de ejecución estructurado, en particular con la estructura
selección, que C++ implementa con las sentencias if, if-else, y switch.
En próximas secciones vamos a presentar esta alternativa.
2.2.1. Absoluto
int Abs(int);
assert( 42 == Abs(-42) );
assert( 0 == Abs( 0) );
assert( 42 == Abs( 42) );
Este es el estilo que vamos a aplicar en el resto del texto, con el objetivo de
ser más claro y establecer una analogía más fuerte entre matemática y C++. En
matemática, primero se escribe el resultado y luego la condición:
12
Step
x<0 ? x
2.2.2. Step
^ /
| /
| /
6 )---[
| /
| /
---3---[
|
|
<--0---4--7---11---->
double Step(double);
assert( 3 == Step(-2 ) );
assert( 3 == Step( 0 ) );
assert( 3 == Step( 3 ) );
assert( 3 == Step( 4 ) );
assert( 4.5 == Step( 5.5) );
assert( 6 == Step( 7 ) );
assert( 6 == Step( 8 ) );
assert( 6 == Step(11 ) );
assert( 8 == Step(13 ) );
13
Funciones de Varias Variables
+
— Campo Escalar: 2 →1
x<4 ? 3 :
4<=x and x<7 ? x-1 :
7<=x and x<11 ? 6 :
x-5 ;}
+
2.3. Funciones de Varias Variables — Campo Escalar: 2 →1
2.3.1. Promedio
double Avg(int,int);
Los parámetros se separan con coma. Los nombres de los parámetros son
opcionales.
assert( 3 == Avg( 2, 4) );
assert( 1 == Avg( 1, 1) );
assert( 0 == Avg( 0, 0) );
assert( 0 == Avg(-1, 1) );
assert( 1.5 == Avg( 1, 2) );
14
Máximo
2.3.2. Máximo
int Max(int,int);
assert( 0 == Max( 0, 0) );
assert( -1 == Max( -1,-1) );
assert( 42 == Max( 42,42) );
assert( 42 == Max( -2,42) );
assert( 42 == Max( 42,-2) );
assert( -2 == Max(-42,-2) );
15
16
3
Funciones Sin Datos ni Resultados y
Efecto de Lado
17
Solicitar Nombre
int Const42();
assert( 42 == Const42() );
La función no recibe argumentos pero puede generar un valor, en este caso 42,
gracias que en la propia definición de la función está el valor 42 hardcodeado.
Esta función tampoco recibe argumentos, pero logra generar un valor al extraer
un dato del objeto global cin mediante el operador >>.
18
Transparencia Referencial y Efecto de Lado
string SolicitarNombre();
string SolicitarNombre(){
cout << "Ingrese un nombre simple: "; // No acepta nombre con espacios.
string nombre;
cin >> nombre;
cout << "\n";
return nombre;
}
La función Const42 y todas las funciones vistas en las anteriores secciones tienen
transparencia referencial [RefTrans] porque pueden ser reemplazadas por el
valor que generan sin afectar el comportamiento del programa y su valor solo
depende de sus argumentos.
Las funciones con transparencia referencial y sin fecto de lado son llamadas
funciones puras.
+
3.3. Imagen Vacía: Funciones sin Resultados (0 →0)
Las funciones void son las funciones que no retornan resultados; tienen
prototipos de la forma void f(...);. El tipo void es el tipo que no contiene
valores, esto es, su conjunto de valores es vacío. Como estas funciones no
19
Saludos
retornan un valor, se las invoca por su efecto de lado, es decir, por cambios que
pueden producen sobre objetos de nuestros sistema.
3.3.1. Saludos
1.
2.
/* Hi
JMS
2018 */
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
int main(){
20
Mostrar Adición de Dos Números Solicitados
void SaludarAlMundo();
SaludarAlMundo();
void Saludar(string);
Saludar("Mundo");
Saludar("León");
string SolicitarNombre();
Saludar(SolicitarNombre());
}
void SaludarAlMundo(){
cout << "Hola, Mundo!\n";
}
string SolicitarNombre(){
cout << "Ingrese un nombre simple: "; // No acepta nombre con espacios.
string nombre;
cin >> nombre;
cout << "\n";
return nombre;
}
21
Mostrar Adición de Dos Números Solicitados
/* AskAddShow
JMS
2018 */
#include <iostream>
int main(){
void MostrarAdicionDeDosNumerosSolicitados();
MostrarAdicionDeDosNumerosSolicitados();
}
void MostrarAdicionDeDosNumerosSolicitados(){
int SolicitarNumero(){
std::cout << "Ingrese un número entero: ";
int n;
std::cin >> n;
std::cout << '\n';
return n;
}
22
Mostrar Adición de Dos Números Solicitados
Esta invocación es especial. Para resolverla primero hay que resolver las
dos invocaciones a SolicitarNumero. Los strings resultantes de sendas
invocaciones a SolicitarNumero son los argumentos a MostrarAdicion.
23
24
4
Recursividad en Funciones Puras
Las funciones recursivas son las que en su definición incluyen por lo menos una
referencia, ya sea directa o indirecta, a la misma función. Por eso las funciones
recursivas denotan repeticiones.
Iteración
Otra alternativa para representar repetición es mediante control de flujo
de ejecución estructurado, en particular con la estructura iteración, que C
++ implementa con las sentencias for, while , y do-while. En próximas
secciones vamos a presentar esta alternativa.
unsigned Sum(unsigned);
assert( 0 == Sum( 0) );
assert( 1 == Sum( 1) );
assert( 3 == Sum( 2) );
assert( 10 == Sum( 4) );
assert( 55 == Sum( 10) );
25
Sumatoria de los Primeros n Naturales
26
5
Rol de los Parámetros: In, Out, e
InOut
Los parámetros de una función cumplen el rol de ser los datos, es decir lo dado
como input (entrada), a la función para calcular su resultado. Asimismo, el output
(salida) o resultado del cálculo es el valor de la expresión de invocación.
Pero vamos a ver que los parámetros pueden utilizarse también como otro como
mecanismo para generar el output (resultado o salida) de la función.
Al rol del parámetro también se lo conoce como modo del parámetro. Los roles o
modos de los parámetros toman los siguientes nombres cortos: in, out, e inout.
#include <cassert>
int main(){
int Suma1(int,int);
27
Parámetro Out
int i{5};
assert( 7 == Suma1(2,i) );
}
int Suma1(int a, int b){
return a+b;
}
#include <cassert>
int main(){
void Suma2(int,int,int&);
int s;
Suma2(2,5,s);
assert( 7 == s );
}
void Suma2(int a, int b, int& c){
c=a+b;
}
La declaración indica que espera tres argumentos, los primeros dos son int y
el segundo es una referencia a un int. La función no retorna valor por que lo
devuelve por el tercer argumento.
Para pensar. ¿Es correcto inicializar s? ¿Por qué? ¿Puede el compilador detectar
la situación?
28
6
Funciones y Campos Vectoriales
+
(0⁺→2 )
29
30
7
Pasaje de Argumentos
31
32
8
Changelog
2.0.0+2023-05-29
• Reestructuración y extensión del del paper.
• Se ocultan la mayoría de las notaciones en asciimath.
• Más explicaciones en la introducción
33
34
Bibliografía
https://en.wikipedia.org/wiki/Test-driven_development.
https://en.wikipedia.org/wiki/cassert
https://math.stackexchange.com/questions/789123/why-is-there-no-function-
with-a-nonempty-domain-and-an-empty-range
https://en.wikipedia.org/wiki/Side_effect_(computer_science)
https://en.wikipedia.org/wiki/Referential_transparency
https://en.wikipedia.org/wiki/Pure_function
https://en.wikipedia.org/wiki/Structure_chart
35
36