Beruflich Dokumente
Kultur Dokumente
Funciones
Funciones
Las funciones constituyen una herramienta esencial en la programación modular. Por un lado,
permiten desarrollar sólo una vez procedimientos (rutinas o, mejor, subrutinas) que son de
utilización frecuente o que se utilizan en diferentes lugares de un mismo programa; por otro lado,
permiten utilizar mecanismos de abstracción que facilitan la construcción de un programa
concentrándose en los aspectos más relevantes y despreocupándose de detalles que pueden ser
encarados en otra etapa del diseño.
Una función es, básicamente, un subprograma; por lo tanto, tiene una estructura similar a la de
cualquier programa:
sólo que interactúa (se comunica) con otra función o directamente con el programa principal; dicha
comunicación se establece a través de argumentos (parámetros) que conforman los datos (entradas)
y resultados (salidas). Como cualquier programa, utilizan variables de trabajo denominadas
variables locales proveyendo mecanismos de protección que hacen a éstas inaccesibles desde
cualquier otro ámbito fuera del de la misma función.
Para invocar a una función (utilizarla en un programa o en otra función) basta con mencionar su
nombre y, entre paréntesis, la lista de parámetros con que se la quiere usar, especificando sólo el
nombre de cada uno. Estos parámetros se denominan reales (o actuales).
Mediante las funciones pueden implementarse procesos equivalentes a operadores (éstos tienen uno
o más operandos -argumentos de entrada- y devuelven un determinado valor de un cierto tipo de
datos) o procedimientos (que procesan un conjunto de entradas para obtener un conjunto de
salidas).
En los lenguajes de programación existen una buena cantidad de funciones predefinidas que nos
facilitan la tarea al despreocuparnos de su complejidad.
Funciones operadores.
Tienen sólo una salida de tipo de datos elemental (tipos de datos predefinidos en el lenguaje) y cero,
uno o más argumentos (entradas). La salida es el valor devuelto por la función.
Ejemplos.
1. Función que calcula el factorial de un número. El factorial de un número n (se escribe n!) es
la productoria de los naturales 1, 2, 3 …. n-1, n;
Ej.: 5! = 5 x 4 x 3 x 2 x 1=120.
Elementos:
• Tipo de dato que devuelve: entero
• Nombre : factorial
• Argumentos:
o Parámetros de entrada: n, entero
o Parámetros de salida : no tiene (La única salida es lo que devuelve).
• Precondiciones: n ≥ 0
• Poscondiciones: f = n * (n-1) * (n-2) * . . . . 3 * 2* 1.
• Cuerpo de la función: proceso de cálculo del factorial y devolución del resultado (f).
Elementos:
• Tipo de dato que devuelve: entero
• Nombre : combinatorio
• Argumentos:
o Parámetros de entrada: a, b: entero
o Parámetros de salida : no tiene.
• Precondiciones : b ≥ 0 y a ≥ b
• Cuerpo de la función: proceso de cálculo del combinatorio y devolución del
resultado.
Funciones procedimientos.
Tienen ninguna salida, una salida de tipo de datos no elemental o más de una salida y cero, uno o
más argumentos (entradas). Normalmente no devuelven nada (tipo de dato de la función es void)
aunque, en el lenguaje C, puede usarse el valor devuelto como una de las salidas cuando ésta es de
tipo elemental. Algunos ejemplos de estas funciones en el lenguaje C:
• printf(“El factorial de %d es %d”, n, f); No tiene parámetros de salida
• scanf(“%d %d %d”, &d, &m, &a); Tiene tres parámetros de salida (y uno de entrada)
Antes de ejemplificar el desarrollo de funciones de este tipo, hay que analizar los mecanismos de
intercambio de parámetros cuando se invoca a una función, conocidos como métodos de sustitución
de parámetros.
En la invocación de la función, los parámetros que se pasan se denominan parámetros reales (o
actuales); En el desarrollo de la función, los parámetros de la misma de denominan parámetros
formales.
Los métodos de sustitución de parámetros son los mecanismos que permiten establecer la relación
entre los parámetros reales y los formales correspondientes.
Básicamente existen dos métodos, llamados por valor y por referencia.
Sustitución por valor: el parámetro formal toma como valor una copia del parámetro real. Esto
tiene como consecuencia directa que los cambios que eventualmente se realicen en la función sobre
los parámetros formales (que son locales de la función) no afectan a las variables utilizadas como
parámetros reales. Por ese motivo, este método se utiliza sólo para parámetros de entrada.
Sustitución por referencia: El parámetro formal es una referencia del correspondiente parámetro
real; su valor no es el valor del parámetro real sino su dirección de memoria por lo que cualquier
cambio que se haga en el parámetro formal repercute en el real (ya que son la misma cosa). Este
método es necesario utilizar en los parámetros de salida (o de entrada/salida)
Elementos:
• Tipo de dato que devuelve: void
• Nombre : obtenerFechaDiaSiguiente
• Argumentos:
o Parámetros de entrada: dh, mh, ah: entero
o Parámetros de salida : ds, ms, as: entero.
• Precondiciones : dh, mh y ah cumplen con los requisitos de una fecha.
• Poscondiciones: ds= ds+1 o ds=1 si dh es el último día del mes.
ms = mh o ms=mh+ 1 si dh es el último día del mes o
ms = 1 si dh es el último día del mes y mh =12
as = ah o as = ah + 1 si dh es el último día del mes y mh =12
• Cuerpo de la función: proceso de obtención del día siguiente.
Para definir los parámetros de salida en el encabezamiento de la función, se antepone, a cada uno de
ellos, la palabra REF.
obtenerFechaDiaSiguiente
int dh, int mh, int ah,
, void
REF int ds, REF int ms, REF int as
ds dh+ 1 Precondiciones
dh, mh, ah
ms mh
corresponden a una
fecha válida
as ah
ds ds - cantidadDiasDelMes(ms,
, as)
ms ms + 1
ms > 12
ms 1
as as + 1
Programa que lee una fecha y, si es válida, obtiene la correspondiente al día siguiente.
d, m, a
esFechaValida (d, m, a)
Codificación en C.
Funciones operadores.
Ejemplos: Función factorial
Función combinatorio
Cuando se utilizan funciones en un programa, antes de la función main deben incluirse los
prototipos (encabezamiento de la función) de las funciones que el mismo utiliza.
Ejemplos:
1. Leer un número y calcular e imprimir su factorial
#include <stdio.h>
int factorial (int); //En el prototipo, el nombre de los parámetros es opcional)
int main()
{
int x, fact;
printf(“\nIngrese un entero para calcular su factorial\n”);
scanf(“%d”, &x);
if(x>=0) //Se controla que se cumpla con la precondición de la función
{
fact = factorial(x);
printf(“\nEl factorial de %d es %d”, x, fact);
}
else
printf(“\nNo se puede calcular el factorial de ”
“un número negativo”);
return 0;
}
#include <stdio.h>
int factorial (int);
int combinatorio(int, int);
int main()
{
int p, q;
printf(“\nIngrese dos enteros para calcular el “
“combinatorio del primero sobre el segundo: \n”);
scanf(“%d %d”, &p, &q);
if(q>=0 && p >=q) //Se controla que se cumpla con las precondiciones
printf(“\nEl combinatorio %d / %d es %d”,
p, q, combinatorio(p,q);
else
printf(“\nNo se cumplen los prerrequisitos para “
“el cálculo del combinatorio”);
return 0;
}
Estas funciones utilizan parámetros de salida o de entrada/salida. Esto implica el uso del método de
sustitución de parámetros por referencia. El problema es que el lenguaje C no prevé este método de
sustitución: sólo usa sustitución por valor. Para resolver los parámetros de salida (o de
Entrada/Salida) en lugar de pasar el parámetro real, pasa su dirección (Esto explica el uso del &
precediendo a la variable en la función scanf: el operador & devuelve la dirección de memoria de su
operando). El parámetro formal entonces debe ser un puntero (variable que contiene una dirección
de memoria).
Definiciones.
Puntero: variable cuyo contenido es una dirección de memoria. Como cualquier variable,
tiene un tipo de dato que es el de la variable real a la que apunta. Se define:
tipo_de_dato * nombre_del_puntero;
Operador &: devuelve la dirección de memoria de su operando
&x se lee la dirección de x. Contiene la dirección de memoria de x.
Operador *
o En una expresión, precediendo al nombre de un puntero, devuelve el valor
contenido en la dirección de memoria representada en el puntero
(Desrreferenciación).
o En la declaración de una variable y precediendo al nombre de la misma, define a
ésta como un puntero.
Ejemplos
Al codificar la función, los parámetros pasados por referencia se definen como punteros al tipo de
dato correspondiente, cuyos nombres pueden ser los del diagrama anteponiéndoles la letra p.
Además, se sugiere definir variables locales correspondientes a cada parámetro de salida con el
nombre de ellos y trabajar con ellas de acuerdo al diagrama. Finalmente, se desreferencia cada
puntero con el valor de la variable correspondiente.
Ejemplo.
1. Obtener la fecha del día siguiente.
La función cantidadDiasDelMes (int m, int a) devuelve la cantidad de días que tiene el mes m
del año a (28, 29, 30 ó 31).
#include <stdio.h>
int esFechaValida(int d, int m, int a);
void obtenerFechaDiaSiguiente(int d, int m, int a, int*pd, int* pm, int*pa);
int main()
{
int d, m, a, dm, mm, am;
printf(“\nIngrese la fecha de hoy (d m a): ”);
scanf(“%d %d %d”, &d, &m, &a);
if(esFechaValida(d, m, a))
{
obtenerFechaDiaSiguiente(d, m, a, &dm, &mm, &am);
printf(“\nEl dia siguiente a %d/%m/%a es %dm/%mm/&am”);
}
else
printf(“\nLa fecha %d/%d/%d no es valida”, d, m, a);
}
Funciones booleanas.
Las funciones booleanas son funciones operadores que generalizan operadores booleanos es decir,
devuelven valores booleanos (verdadero o falso). Luego, pueden ser usadas como operandos en
expresiones booleanas. Es por ello que es importante la elección del nombre de la función de modo
que su uso permita la escritura (y la interpretación) clara del algoritmo.
Veamos ejemplos:
1. La función hay_datos podría utilizarse para controlar el ingreso de datos desde el teclado.
Interactúa con el operador con el objeto de que éste decida cuándo termina el ingreso de los
mismos. Además, constituye un ejemplo de función sin argumentos.
DIAGRAMA hay_datos
Cómo usar la función hay_datos:
Leer un conjunto de enteros e informar cuántos de ellos son pares.
int hay_datos()
{
char resp;
printf("\nHay datos? (S/N)");
fflush(stdin);
scanf("%c", &resp);
resp=toupper(resp);
while(resp!='S' && resp!='N')
{
printf("\nDebe responder S o N");
printf("\nHay datos? (S/N)");
fflush(stdin);
scanf("%c", &resp);
resp=toupper(resp);
}
return resp=='S';
}
int main()
{
int n, cant=0;
int cant_dias_mes(m, a)
{
int cd = 31;
if(m == 4 || m == 6 || m == 9 || m == 11)
cd = 30;
else
if(m == 2)
if(es_bisiesto(a))
cd = 29;
else
cd = 28;
return cd;
}
int es_bisiesto(int a)
{
int eb= 0;
if(a % 400 == 0)
eb = 1;
else
if(a % 4 == 0 && a % 100 != 0)
eb=1;
return eb;
}
3.