Funciones y Parámetros
! Funciones ! Concepto ! Argumentos
! Programa Principal ! Recursividad
El programa principal ■ Es el punto de entrada al programa ■ Imprescindible para conseguir un
ejecutable autónomo o “programa” ■ Mínimo programa totalmente correcto
int main(void) { return 0; }
Programación C++ 2 © Francisco Rosales, Jose María Peña & Jesús Montes
Concepto de función
Programación C++ 3 © Francisco Rosales, Jose María Peña & Jesús Montes
Función y procedimiento ■ Semejante a función matemática ■ Invocación, argumentos, valor
devuelto ■ Un único punto de entrada ■ Un único punto de salida
■ Procedimiento ■ Si no devuelve ningún valor
Programación C++ 4 © Francisco Rosales, Jose María Peña & Jesús Montes
Funcionalidades ■ Crear una función para cada
funcionalidad o método bien delimitado de cada módulo del programa ■ ¡Aunque sólo se use una vez! ■ Programa = conjunto de funciones
Programación C++ 5 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – descripción I ■ Qué es lo que hace (funcionalidad) ■ El nombre debe resumirlo ■ Ejemplo clásico ■ factorial(n) = n * (n-1) * ... * 2 * 1 ■ factorial(0) = 1 ■ Para n natural (entero no negativo)
Programación C++ 6 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – descripción II Una función se invoca proporcionando valores a los argumentos de la llamada. ■ El valor se devuelve por medio de return. ■ El control del número y tipo de
argumentos es mínimo. ■ Las funciones en C++ admiten
recursividad.
Programación C++ 7 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – declaración ■ Dice cómo se usarla ■ No dice cómo está hecha ■ Se declara su prototipo
unsigned factorial(unsigned);
Programación C++ 8 © Francisco Rosales, Jose María Peña & Jesús Montes
Qué devuelve (tipo)
Qué hace (nombre)
Qué recibe (tipo)
Punto y coma
Función – invocación II int main(void) { cout <<"3! = "<<factorial(3)<<endl; cout <<"7! = "<<factorial(7)<<endl; return 0; }
■ Varias invocaciones a la misma función son independientes
Programación C++ 9 © Francisco Rosales, Jose María Peña & Jesús Montes
Argumento
Función – definición unsigned factorial(unsigned n)
{
unsigned result = 1;
/* Recorre de n a 2 */
for (; n > 1; n--)
result = result * n;
return result;
}
Programación C++ 10 © Francisco Rosales, Jose María Peña & Jesús Montes
Parámetro formal Variable local
Paso de parámetros ■ Paso por valor: ■ La función trabaja
con una copia del valor del parámetro. ■ Se considera un
parámetro de entrada.
■ Paso por referencia: ■ Se distingue
poniendo & delante del parámetro. ■ La función trabaja
con la variable de entrada directamente.
Programación C++ 11 © Francisco Rosales, Jose María Peña & Jesús Montes
Paso por valor int main(void) { unsigned num = 5, res; res = factorial(num); /* num sigue valiendo 5 */ ■ Se pasa el valor de la expresión evaluada,
no la variable en sí ■ Esto es siempre así en C ■ En C++ existe el paso por referencia
Programación C++ 12 © Francisco Rosales, Jose María Peña & Jesús Montes
Paso por referencia ■ Solo se pueden
usar variables como parámetros. ■ Los parámetros se
pueden modificar. ■ Podemos crear
procedimientos (funciones de tipo void).
void incremento (int &a) {
a = a + 1;
}
int main () {
int a = 0;
incremento(a);
// Ahora a vale 1
return a;
}
Programación C++ 13 © Francisco Rosales, Jose María Peña & Jesús Montes
La función main ■ El programa principal es una función
como las demás: ■ Es la primera que se ejecuta. ■ Sirve de punto de inicio del programa. ■ Se denomina función principal (en
inglés: main function).
Programación C++ 14 © Francisco Rosales, Jose María Peña & Jesús Montes
Argumentos de invocación I ■ Los argumentos con los que es
invocado el ejecutable son accesibles desde la función principal main
int main(int argc, char* argv[]) int argc : Número de argumentos char* argv[] : Argumentos de invocación
Programación C++ 15 © Francisco Rosales, Jose María Peña & Jesús Montes
Argumentos de invocación II $ g++ prog.cpp -o prog $ ./prog uno dos tres cuatro
Programación C++ 16 © Francisco Rosales, Jose María Peña & Jesús Montes
int main(int argc, char* argv[]) argc == 5
argv[0] p r o g \0 argv[1] u n o \0 argv[2] d o s \0 argv[3] t r e s \0 argv[4] c u a t \0 r o
NULL argv[5]
Argumentos de invocación III #include <iostream> using namespace std; int main(int argc, char *argv[]) { cout <<"Ejecutable: "<<argv[0]<<endl; for(int i=0; i<argc; i++) cout<<"Argumento["<<i<<"]: "<<argv[i]<<endl; return 0;
}
Programación C++ 17 © Francisco Rosales, Jose María Peña & Jesús Montes
Ejercicio
Programe:
La función principal de un programa que
muestre el factorial de los números
del 0 al 20 inclusive
Programación C++ 18 © Francisco Rosales, Jose María Peña & Jesús Montes
Solución
#include <iostream>
using namespace std;
int main(void)
{
unsigned n;
for (n = 0; n <= 20; n++)
cout <<n<<"! = "<<factorial(n)<<endl;
return 0;
}
Programación C++ 19 © Francisco Rosales, Jose María Peña & Jesús Montes
Ejercicio
Programe la siguiente función definida sobre
m y n naturales
binomial(m,n) = m! / (n!*(m-n)!)
Programación C++ 20 © Francisco Rosales, Jose María Peña & Jesús Montes
Solución
unsigned binomial(unsigned m, unsigned n)
{
return factorial(m) / (factorial(n)*factorial(m-n));
}
Programación C++ 21 © Francisco Rosales, Jose María Peña & Jesús Montes
Ámbito de las variables I ■ La declaración de las variables lleva
asociado un ámbito, dentro del cual la variable es visible: ■ Ámbito global: La variable es visible para
todas las funciones del programa. ■ Ámbito local: La variable es visible sólo
dentro de la función (tiene prioridad sobre el ámbito global).
Programación C++ 22 © Francisco Rosales, Jose María Peña & Jesús Montes
Ámbito de las variables II
int x,y;
int main()
{
float x,z;
// Aquí x y z son reales e y un entero
}
// Aquí x e y son variables enteras
// La variable z no existe fuera de la
// función.
Programación C++ 23 © Francisco Rosales, Jose María Peña & Jesús Montes
Arrays como parámetros I ■ Los arrays como parámetros se
pueden modificar dentro de la función ■ Se debe tener en cuenta el tamaño y
número de dimensiones del array ■ En caso de que se desconozca el
tamaño, se debe indicar como parámetro, si la función lo requiere ■ En char[] se usa ‘\0’ para indicar el final
Programación C++ 24 © Francisco Rosales, Jose María Peña & Jesús Montes
Arrays como parámetros II
int suma (int lista[], int num_elem) {
int i;
int acumulador = 0;
for (i=0; i < num_elem; i++) {
acumulador = acumulador + lista[i];
}
}
return acumulador;
}
Programación C++ 25 © Francisco Rosales, Jose María Peña & Jesús Montes
Arrays como parámetros III
int contar_letras (char letra, char cadena[]) {
int contador = 0;
for (int i=0; cadena[i] != '\0'; i++) {
if (cadena[i] == letra) {
contador++;
}
}
return contador;
}
Programación C++ 26 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – recursividad I ■ Facultad de las funciones de invocarse
a sí mismas ■ Forma natural de expresar ciertos
problemas autocontenidos ■ Ejemplo clásico ■ factorial(n) = n * factorial(n-1) ■ factorial(0) = 1
Programación C++ 27 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – recursividad II ■ Estructura tipica de una función
recursiva:
tipo func_recursiva(...) {
...
if (!condición_parada) {
...
func_recursiva(...);
} else {
...
}
}
Programación C++ 28 © Francisco Rosales, Jose María Peña & Jesús Montes
Ejercicio
Programe:
Una versión recursiva de la función:
factorial(0) = 1 factorial(n) = n * factorial(n-1)
Para n natural (entero no negativo)
Programación C++ 29 © Francisco Rosales, Jose María Peña & Jesús Montes
Solución unsigned factorial(unsigned n)
{
if (n == 0)
n = 1;
else
n = n * factorial(n - 1);
return n;
}
Programación C++ 30 © Francisco Rosales, Jose María Peña & Jesús Montes
Función – recursividad III ■ Funcionalmente equivalente iterar ■ La implementación: ■ no contiene ningún bucle ■ pero si una condición de terminación
■ Es mucho más difícil de seguir ■ La recursión infinita es fatal
Programación C++ 31 © Francisco Rosales, Jose María Peña & Jesús Montes
Recursividad vs. Iteración
int fact(int num) {
int val = 0;
if (num > 0) {
val = num*fact(num-1);
} else {
val = 1;
}
return val;
}
int fact(int num) {
int ret = 1;
int val = num;
while (val > 0) {
ret = ret * val;
val--;
}
return ret;
}
Programación C++ 32 © Francisco Rosales, Jose María Peña & Jesús Montes
Modificadores de función static ■ Sólo visible dentro del módulo
extern ■ Función (o variable) declarada, pero definida en
algún otro sítio (Ej. en biblioteca)
inline ■ Expandir su código en vez llamar a la función ■ Aumenta la eficiencia y el tamaño del código
Programación C++ 33 © Francisco Rosales, Jose María Peña & Jesús Montes
Herramientas de Desarrollo II
! Estructuración de código ! Compilación separada ! Archivador y bibliotecas ! Constructor y otras
Estructuración de código ■ El uso de funciones permite organizar el
código de un programa en bloques sencillos. ■ Las tareas comunes que se repiten a lo largo
del programa se deben separar en funciones. ■ Facilita la organización del programa ■ Evita replicación del código ■ Hace mas sencilla la depuración
■ Mejor un programa con muchas funciones pequeñas que con una única grande.
Programación C++ 35 © Francisco Rosales, Jose María Peña & Jesús Montes
Estructuración en ficheros ■ Las funciones de un programa se pueden
repartir en varios ficheros para facilitar su organización. ■ Los diferentes grupos de funciones se
organizan en pares de ficheros .h/.cpp ■ El .h contiene las declaraciones de las funciones ■ El .cpp contiene su implementación. Puede incluir
también una función principal (main).
Programación C++ 36 © Francisco Rosales, Jose María Peña & Jesús Montes
Compilación y montaje Son etapas separadas
■ Compilación: traducir de formato fuente a formato objeto (lenguaje máquina, más lista de referencias externas no resueltas) ■ Montaje: enlazar ficheros objeto entre sí y
con las bibliotecas necesarias, resolviendo todas las referencias externas ■ Se produce un ejecutable: en formato
interno apto para situar el proceso en memoria para su ejecución
Programación C++ 37 © Francisco Rosales, Jose María Peña & Jesús Montes
Ficheros .h y .cpp ■ operaciones.h
int suma (int a, int b);
int factorial (int num);
■ operaciones.cpp
int suma (int a, int b) {
int s;
s = a + b;
return s;
}
int factorial (int num) {
int ret = 1;
while (num > 1) {
ret = ret * num--;
}
return ret;
}
Programación C++ 38 © Francisco Rosales, Jose María Peña & Jesús Montes
Inclusión de Ficheros I ■ Los prototipos de las funciones usadas por varios
ficheros fuente se suelen definir en un fichero de cabecera
#include <iostream> Cabeceras del sistema #include "mis_func.h" Ficheros de cabecera locales.
Programación C++ 39
#include “aux.h” int main() { ...}
fich.cpp
int func1(int a); viod func2();
aux.h int func1(int a); viod func2(); int main() { ...} Preprocesamiento
© Francisco Rosales, Jose María Peña & Jesús Montes
Inclusión de Ficheros II ■ La inclusión de ficheros esta sujeta a
las siguientes recomendaciones: ■ Por lo general los ficheros de cabecera
tienen como extensión .h ■ En los ficheros de cabecera no se
incluyen implementación de funciones ■ Las variables en un fichero de cabecera
son declaradas extern y se encuentran declaradas en algún otro fichero .cpp
Programación C++ 40 © Francisco Rosales, Jose María Peña & Jesús Montes
Proceso de compilación
Programación C++ 41 © Francisco Rosales, Jose María Peña & Jesús Montes
.cpp
Fichero Fuente
Preprocesamiento .cpp Paso a Ensamblador .s
.o
Ensamblado Compilación
.o .o .o .o
Enlazado
.a Bibliotecas
Fichero Ejecutable
Compilación separada ■ En la figura: ■ Compilación separada de los módulos ■ main.cpp y prim.cpp
■ Montaje de los objetos con las bibliotecas ■ main.o, prim.o y libstdc++ y otras (libm, libc)
■ Obtención del fichero ejecutable ■ primes
Programación C++ 42 © Francisco Rosales, Jose María Peña & Jesús Montes
Programación C++ 43 © Francisco Rosales & Jose María Peña
Diagrama de fases
prim.h
prim.cpp
main.cpp
cmath
iostream
g++ -c
g++ -c
main.o
prim.o ld primes
cstdlib
libc.a
libm.a
Módulos de
usuario
Ficheros estándar
de cabecera
Compilación separada
Ficheros objeto
Bibliotecas estándar Montaje Ejecutable
Dependen
Fich Herram Producto
Auto
entre si
Leyenda
libstdc++.a
Extensiones ■ Le indican al compilador el contenido de
fichero, y el tratamiento que debe realizar: ■ .c .cpp Fuentes de C y C++ ■ Deben ser preprocesados, compilados y ensamblados
■ .h Fichero de cabecera de C o de C++ (/usr/include y /usr/include/c++) ■ Declaraciones de tipos de datos, prototipos y clases ■ Deben ser preprocesados
■ .o Fichero objeto ■ Deben ser enlazados (resueltos sus símbolos)
■ .a .so Bibliotecas estática y dinámica ■ Para resolver símbolos de funciones estándar usadas
Programación C++ 44 © Francisco Rosales, Jose María Peña & Jesús Montes
Bibliotecas ■ Utilizar código probado, no reinventar ■ Consultar el manual ■ Usar fichero(s) de cabecera
#include <xx.h> /* en C */ #include <xx> // en C++
■ Montar contra la biblioteca (opción –l) ■ libc.a Biblioteca estándar de C ■ Tiras de caracteres, entrada y salida estándar, etc. ■ El montaje contra esta biblioteca es automático
■ libm.a Biblioteca de cálculo matemático ■ sqrt, pow, hypot, cos, atan, etc. ■ Hay que incluir <math.h> o <cmath> ■ Hay que montar con la opción -lm
Programación C++ 45 © Francisco Rosales, Jose María Peña & Jesús Montes
ar Manage Archive ■ Para crear nuestras propias bibliotecas ■ -d Elimina ficheros ■ -r Añade (o reemplaza) ficheros ■ -u Igual que -r sólo si es más nuevo ■ -t Muestra el contenido ■ -v Verbose ■ -x Extrae ficheros
Programación C++ 46 © Francisco Rosales, Jose María Peña & Jesús Montes
Constructor ■ Permite automatizar el proceso de
construcción de un programa que está convenientemente descompuesto en múltiples módulos ■ Herramienta make
Programación C++ 47 © Francisco Rosales, Jose María Peña & Jesús Montes
make Application Maintainer ■ Determina qué partes de un programa
deben recompilarse ■ Debe conocer las dependencias entre
los ficheros: ■ Un fichero debe actualizarse si alguno de
los que depende es más nuevo
■ Makefile ■ Contiene las reglas de dependencia y
mandatos para actualizarlo
Programación C++ 48 © Francisco Rosales, Jose María Peña & Jesús Montes
Makefile I # Esto es un comentario CC=gcc # Esto son macros CFLAGS=-g OBJS2=test.o prim.o all: primes test # Esta es la primera regla primes: main.o prim.o # Esta es otra regla gcc -g -o primes main.o prim.o -lm # Este es el mandato asociado test: $(OBJS2) # Aquí usamos las macros ${CC} ${CFLAGS} -o $@ ${OBJS2} main.o prim.o test.o : prim.h # Esta es una dependencia. clean: # Esta no depende de nada, es obligatoria. rm -f main.o ${OBJS2}
Programación C++ 49 © Francisco Rosales, Jose María Peña & Jesús Montes
Makefile II ■ Las líneas con mandatos deben tabuladas ■ make Dispara la primera regla ■ make clean Explicitando la regla a disparar
■ La regla objetivo dispara sus dependencias recursivamente ■ Macros especiales ■ $@, $*, $<, etc.
■ Se pueden especificar reglas basadas en la extensión de los ficheros ■ Cómo pasar de un .c a un .o
Programación C++ 50 © Francisco Rosales, Jose María Peña & Jesús Montes
Otras herramientas ■ Existen variedad de herramientas útiles para
el desarrollador de código ■ gprof Realizar un perfil de ejecución
Indica dónde se pierde el tiempo Dice qué optimizar
■ gcov Verificación del programa Asegura que el 100% del código han sido comprobado
■ indent Indentación de ficheros fuente en C Da estilo uniforme al código Es muy parametrizable
Programación C++ 51 © Francisco Rosales, Jose María Peña & Jesús Montes