You are on page 1of 11

MANEJO DE FUNCIONES EN C++

GENERALIDADES

Una función es un conjunto de líneas de código que realizan una tarea específica y puede retornar un valor. Las
funciones pueden tomar parámetros que modifiquen su funcionamiento. Las funciones son utilizadas para
descomponer grandes problemas en tareas simples y para implementar operaciones que son comúnmente utilizadas
durante un programa y de esta manera reducir la cantidad de código. Cuando una función es invocada se le pasa el
control a la misma, una ves que esta finalizo con su tarea el control es devuelto al punto desde el cual la función
fue llamada.

Las funciones se declaran y se definen exactamente igual que en C, y, al igual que en éste, se puede utilizar
prototipo (prototype).
Un prototipo es un modelo limitado de una entidad más completa que aparecerá después. En el caso de funciones,
la función es la entidad completa que vendrá después,1 y la declaración de dicha función es el prototipo. El
prototipo da un modelo de la interfaz a la función.

La forma general del prototipo de una función es:

valor-devuelto nombre-función (lista-de-argumentos);

La forma general de la definición es:

valor-devuelto nombre-función (lista-de-argumentos) {


  sentencias;         // "cuerpo" de la función
}

Ejemplo:

float cuadrado (float x);                // prototipo


float cuadrado (float x) { return x*x; } // definición

La comunicación entre el programa y las funciones que lo componen se realiza mediante los argumentos de
llamada, los valores devueltos y las variables globales y externas.

DECLARACIÓN DE FUNCIONES IMPLÍCITAMENTE


# include <iostream.h>

int cuadrado (int x) {return x * x; }

double cuadrado (double y) { return y * y;}

int main ()
{
cout<< "el cuadrado del número 7 tipo integer es "<< cuadrado (7)
<< "\n el cuadrado del número 7.5 tipo double es " << cuadrado (7.5)
<< endl;

return 0;
}

DECLARACIÓN DE FUNCIONES EXPLÍCITAMENTE

# include <iostream.h>

int cuadrado (int );

double cuadrado (double ); 1

int main ()
{
cout<< "el cuadrado del número 7 tipo integer es "<< cuadrado (7)
<< "\n el cuadrado del número 7.5 tipo double es " << cuadrado (7.5)
<< endl;

return 0;
}

int cuadrado (int x)


{
return x * x;
}

double cuadrado (double y)


{
return y * y;
}

USO DE VARIAS FUNCIONES SIMPLES


#include <iostream.h>

float a,b,c;
sumar();
restar();
multiplicar();
dividir();
pedir_datos();
mostrar_resultado();

main()
{
pedir_datos();
sumar();
mostrar_resultado();
pedir_datos();
restar();
mostrar_resultado();
pedir_datos();
multiplicar();
mostrar_resultado();
pedir_datos();
dividir();
mostrar_resultado();
return 0;
}
1
sumar()
{
c=a+b;
}
restar()
{
c=a-b;
}
multiplicar()
{
c=a*b;
}
dividir()
{
c=a/b;
}

pedir_datos()
{
cout<<"da el valor de a";
cin>>a;
cout<<"da el valor de b";
cin>>b;
}
mostrar_resultado()
{
cout<<"el valor de la operacion es "<<c<<endl;
}

CREACIÓN DE NÚMEROS ALEATORIOS Y FORMATOS DE DESPLIEGUE

# include <iostream.h>
# include <iomanip.h>
# include <stdlib.h>
# include <ctime>

# define random(x) (rand() % x)

int main()
{
for (int i=1;i<=20;i++)
{
cout<< setw (10) << ( 1+ random(6) % 6 );

if (i%5==0)
cout << endl;
} 1
return 0;
}

C++ ofrece 4 especificadores de clase de almacenamiento: auto, register, extern y static. El especificador de
almacenamiento de un identificador permite determinar su clase de almacenamiento, alcance y enlace.

La clase de almacenamiento determina el periodo durante el cual existe en memoria dicho identificador. Algunos
identificadores existen durante un corto periodo de tiempo, otros se crean y se destruyen repetidamente y otros
existen durante toda la ejecución del programa.

Las variable locales declaradas con la palabra clave static siguen siendo conocidas sólo en la función en la que se
definen pero, a diferencia de las variables automáticas, las variables static locales conservan sus valores al salir de
la función. La siguiente vez que se llama a la función, las variables locales static contendrán los valores que tenían
al salir de ella la última vez.

DECLARACIÓN
static int count = 1 ;

FUNCIONES RECURSIVAS
Un tema fundamental para los próximos temas es el de recursión. La recursión es muy importante tanto en
matemáticas como en computación, pues se usa recursión para definir procedimientos autosimilares.

Definición. Decimos que un objeto es recursivo si en su definición se nombra a sí mismo.

En programación, una función es recursiva si en el ámbito de esa función hay una llamada a sí misma, C/C++
permite esta clase de acciones. Los algoritmos recursivos dan elegancia a las soluciones de los problemas. Un
ejemplo clásico es el factorial de un número.

Una manera de definir el factorial de un número i>1 es:

es decir, el producto de todos los números enteros menores o guales que él, lo que se puede resolver fácilmente con
una función iterativa, esto es, una función con un ciclo que itere suficientes veces, incrementando un valor y
entonces ir almacenando en una variable el resultado de esas multiplicaciones.

Una implementación de esta definición iterativa es:

(1) int i,n;


(2) long double valorAc;
1
(4) valorAc=1.0;
(5) std::cout << "Numero entero:";
(6) std::cin>> n;
(7) for(i=1; i<=n; i++) valorAc = valorAc*i;
(8) std::cout<<"El factorial de "<<n<<" es:"<<valorAc;

El ciclo principal es en la línea (7). No hay ningún truco hasta aquí. La única observación importante es en la línea
(2) en donde se declara el tipo long double para el valor del resultado, la razón para tal acción es que el número
factorial crece muy rápido y aún con entradas en el rango de los caracteres (hasta 255), el factorial es muy grande.
Este procedimiento computacional no hace uso de técnicas especiales empleadas para tratar números grandes.

Sin embargo una solución más elegante es usar la definición recursiva, y esta es:

El programa en C/C++ es el que se muestra a continuación:

( 1) double factorial(double a){


( 2) if (a<=1) return 1.0;
( 3) else return (a *factorial(a-1.0)); }
( 4)
( 5) int main (int argc, char * const argv[]) {
( 6) double n;
( 7) std::cout << "Numero entero:";
( 8) std::cin>> n;
( 9) std::cout<<"El factorial de "<<n<<" es: "<< factorial(n);
(10) return 0; }

Aquí hay varias cosas que señalar, en primer lugar se ha creado una nueva función, a diferencia de la definición
iterativa en donde era suficiente trabajar en el programa principal. Esta función se llama factorial (como era de
suponerse), y empieza su encabezado en la línea (1).

Allí mismo en la misma línea (1), es de notar que hemos empleado ahora el tipo double tanto para el tipo devuelto
como para el tipo del argumento, a diferencia de la versión iterativa en donde empleábamos tipos diferentes. La
razón es que al iniciar la recursión el argumento es del tipo devuelto, asi que deben ser del mismo tipo.

Cada llamada recursiva genera una entrada a una pila, en donde se guardan (como elementos) los estados generales
del sistema al momento de hacer la llamada, entonces, cuando se termina la función se recupera una entrada de la
pila.

La serie Fibonacci
Una de las series más famosas es sin duda alguna la serie de Fibonacci:

Un poco de observación es sufucuente para encontrar que cualquier número (a partir del tercero de la serie, osea el
segundo 1) es igual a la suma de los dos números anteriores.
1

Daremos en primer lugar la versión iterativa. En este algoritmo deseamos encontrar el -ésimo número de la serie
Fibonacci. Así si el resultado del algoritmo debe ser ; si el resultado debe ser . La versión iterativa empieza desde
los primeros 1's, sumándolos y encontrando el tercero, luego para encontrar el cuarto número se suman el tercero
(recién encontrado) y el segundo, y así en adelante hasta encontrar el número buscado.

#include <iostream>

int main (int argc, char * const argv[]) {


int i,n,fib,fib1,fib2,fibx;

std::cout<<"Un numero entero:";


std::cin>>n;
fib1=2; fib2=1; i=3;
if((n==1)||(n==2))
fib=1;
else{
do{
fib = fib1 + fib2;
fibx = fib1; i++;
fib1 = fib; fib2 = fibx;
}while(i<n);
}
std::cout << "\nEl "<<n<<"-esimo numero de
la serie Fibonacci es: "<<fib;
return 0;
}

La definición recursiva para encontrar todos los primeros números de la serie Fibonacci es:

En el siguiente código, la solución que propone la recursividad resulta en una programación elegante, aunque
costosa. El código que hace esto es:

( 1) #include <iostream>
( 2) //====================
( 3) int fib(int val){
( 4) if ((val==1)||(val==2))
( 5) return 1;
( 6) else
( 7) return (fib(val-1)+fib(val-2));
( 8) }
( 9) //====================
(10) int main (int argc, char * const argv[]) { 1
(11) int n;
(12) std::cout<<"Numero entero:"; std::cin>>n;
(13) std::cout<<"\nEl "<< n
(14) <<"-esimo numero fibonacci es: "<< fib(n);
(15) return 0;
(16) }

Como regla general, cualquier algoritmo recursivo se puede reescribir en un algoritmo iterativo. La ventaja de tener
un algoritmo iterativo es que no se usa una pila para guardar llamadas a la misma función de manera recursiva, esto
es una ventaja porque el espacio de memoria destinado al uso de la pila es generalmente limitado, de manera que
cuando se hacen demasiadas funciones push seguramente llegará el momento en que la pila ``se desborde'', que por
cierto es un término usado en computación para decir que ya no hay más espacio disponible en la pila.

SOBRECARGA DE FUNCIONES

En C++ dos o más funciones pueden compartir el mismo nombre en tanto en cuanto difiera el tipo de sus
argumentos o el número de sus argumentos o ambos. Cuando comparten el mismo nombre y realizan operaciones
distintas se dice que están sobrecargadas. Para conseguir la sobrecarga simplemente hay que declarar y definir
todas las versiones requeridas.
También es posible y es muy común sobrecargar las funciones constructoras. Hay 3 razones por las que
sobrecargar las funciones constructoras. Primero ganar flexibilidad, permitir arrays y construir copias de
constructores.

EJEMPLO:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
int abs(int numero);
long abs(long numero);
double abs(double numero);

void main()
{
clrscr();
cout <<"Valor absoluto de -10 "<< abs(-10) <<"\n";
cout <<"Valor absoluto de -10L "<< abs(-10L) <<"\n";
cout <<"Valor absoluto de -10.01 "<< abs(-10.01) <<"\n";
getch();
}

int abs(int numero)


{
return numero<0 ? -numero:numero;
} 1
long abs(long numero)
{
return numero<0 ? -numero:numero;
}
double abs(double numero)
{
return numero<0 ? -numero:numero;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void fecha(char *fecha);
void fecha(int anno, int mes, int dia);
void main()
{
clrscr();
fecha("23/8/98");
fecha(98,8,23);
getch();
}
void fecha(char *fecha)
{
cout<<"Fecha: "<<fecha<<"\n";
}
void fecha(int anno,int mes,int dia)
{
cout<<"Fecha: "<<dia<<"/"<<mes<<"/"<<anno;
}

ARGUMENTOS IMPLICITOS: Otra característica relacionada con la sobrecarga es la utilización de argumentos


implícitos que permite dar un valor a un parámetro cuando no se especifica el argumento correspondiente en la
llamada a la función.

PROTOTIPO:
tipo_devuelto(var1=valor,var2=valor,varN=valor);

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
void funcion(int a=0, int b=0)
{
cout<<"a: "<< a <<" b: "<< b <<"\n";
}

void main()
{
clrscr();
funcion(); 1
funcion(10);
funcion(20,30);
getch();
}

Es muy similar a la sobrecarga de funciones, un operador siempre se sobrecarga con relación a una clase. Cuando
se sobrecarga un operador no pierde su contenido original, gana un contenido relacionado con la clase. Para
sobrecargar un operador se crea una función operadora que normalmente será una función amiga a la clase.

PROTOTIPO:
tipo_devuelto nombre_clase::operator operador(parametros)
{
cuerpo;
}

Se pueden realizar cualquier actividad al sobrecargar los operadores pero es mejor que las acciones de un operador
sobrecargado se ajusten al uso normal de ese operador. La sobrecarga tiene dos restricciones, no puede cambiar la
precedencia del operador y que el numero de operadores no puede modificarse. También hay operadores que no
pueden sobrecargarse.

PLANTILLAS DE FUNCIONES
1

# include <iostream.h>

template <class T>

T maximum (T value1, T value2, T value3)


{
T max = value1;

if (value2>max)
max = value2;

if (value3>max)
max = value3;
return max;
}

int main()
{
int int1, int2, int3;

cout<<"Introduzca tres valores del tipo integer: ";


cin>>int1>>int2>>int3;

cout<<"El máximo valor de tipo integer es: "


<<maximum(int1,int2,int3);

double double1, double2, double3;

cout<<"Introduzca tres valores del tipo double: ";


cin>>double1>>double2>>double3;

cout<<"El máximo valor de tipo double es: "


<<maximum(double1,double2,double3);

char char1, char2, char3; 1

cout<<"Introduzca tres valores del tipo char: ";


cin>>char1>>char2>>char3;

cout<<"El máximo valor de tipo char es: "


<<maximum(char1,char2,char3)
<<endl;

return 0;
}

You might also like