Professional Documents
Culture Documents
Funciones
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 117 Funciones
1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
7. Bibliografa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
1. Introduccin
Como en otros lenguajes de alto nivel, el C tambin nos ofrece la posibilidad de escribir funciones (sub-
programas). Dependiendo del tipo de lenguaje utilizado, los subprogramas reciben diferentes nombres:
procedimiento, funcin, rutina, subrutina, etc.
El lenguaje C se dise con el objetivo de facilitar la resolucin de programas complejos mediante la uti-
lizacin de funciones. Dividiendo los problemas complejos en problemas ms sencillos, y resolviendo
cada uno de ellos mediante una funcin adecuada, somos capaces de resolver el problema general
(siguiendo la estrategia de divide and conquer). Como ya sabemos esta tcnica es la base de la programa-
cin estructurada y, hoy en da, prcticamente todos los programas se escriben as.
************************************************************************
ETSII y de IT
Alameda Urquijo, sin num.
Bilbao
************************************************************************
#include <stdio.h>
#include <conio.h>
void main ()
{
int cont = 0;
for (cont = 1; cont <= ASTE_CANT; cont ++)
{
putchar (*);
}
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 120 Funciones
putchar (\n);
Como puede verse, en este programa una parte del cdigo est repetida dos veces. Adems el objetivo de
esta parte del cdigo es la misma en los dos casos. Cmo podramos hacer para no escribir dos veces la
misma cosa? La utilizacin de funciones nos da la respuesta a esta pregunta.
Vamos a escribir ahora el mismo programa pero en este caso utilizando las funciones:
#include <stdio.h>
#include <conio.h>
/* Declaracin de prototipos */
asteriscos ();
}
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 121 Funciones
Tal y como puede apreciarse, en este programa llamamos dos veces a la funcin asteriscos () . Cada vez
que la llamamos se ejecuta el cdigo escrito dentro de la funcin. A continuacin veamos como se hara
la definicin de la funcin asteriscos () .
#include <stdio.h>
#define ASTE_CANT 40
2. Objetivos
Como puede verse en el programa anterior, el uso de la funciones comienza con la declaracin de todas
las funciones que se utilizan en el programa. Para ello se debe escribir el prototipo de cada funcin.
Luego se escribe el programa principal y a continuacin las funciones que se utilizan en el programa. Por
lo tanto se distinguen tres secciones, declaracin de funciones o declaracin de prototipos, programa
principal y las llamadas a funciones que este realiza, y por ltimo las funciones, esto es: el cdigo corres-
pondiente a cada funcin. Hay que tener en cuenta que dentro de una funcin pueden existir tambin
llamadas a otras funciones.
Todos los prototipos de funciones utilizadas por el programa se declaran antes de que d comienzo el
programa principal, es decir: antes de escribir la funcin main . De esta manera el compilador reconoce
qu tipo de funcin es, qu tipo de datos da, cuantos parmetros recoge y cuales son sus tipos de datos.
En el ejemplo anterior se procede as:
El primer void expresa que esta funcin no da como resultado de su ejecucin ningn valor. Luego viene
el nombre de la funcin. El segundo void expresa que esta funcin no toma argumentos. Ms adelante
veremos de qu manera da un valor una funcin y cmo se le pasa parmetros.
La definicin de la funcin contina con el cuerpo de la funcin. Escribimos las sentencias necesarias
para conseguir el objetivo de la funcin. Antes de empezar a escribir el cdigo de la funcin, debemos
mostrar de qu tipo de funcin se trata y si no se ajusta a lo declarado en el prototipo, al encontrar el
compilador esa diferencia dir que esas declaraciones no estn de acuerdo. Es por ello que lo que hemos
escrito en la primera lnea y en la declaracin de prototipos son iguales: void asteriscos (void) . Este
ejemplo es muy sencillo pero pensamos que es interesante como punto de partida. En secciones poste-
riores concretaremos el uso de las funciones.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 124 Funciones
Como hemos visto en el ejemplo anterior hemos definido dentro de la funcin la variable cont. Si escri-
bisemos la siguiente sentencia en la funcin main :
el compilador dira que hay un error. Por qu? porque las variables definidas dentro de una funcin slo
son reconocidas dentro de esa funcin. Estas variables se denominan locales. Tambin se dice que estas
variables son automticas ya que se crean al hacer la llamada a la funcin y al finalizar la funcin desa-
parecen automticamente.
En ocasiones nos resulta conveniente definir variables que sean conocidas por todas las funciones. Estas
variables se denominan variables externas y se deben declarar antes de main o de todas las funciones.
Para poder hacer una interpretacin sencilla de los programas, las variables externas deben ser usadas lo
mnimo posible.
En el siguiente ejemplo se muestra cmo se utilizan las variables externas. El objetivo del ejemplo es ave-
riguar si un nmero es par y negativo. Para ello se utiliza la variable externa numero. Por lo tanto esta
variable es conocida tanto en el programa principal como en las funciones.
#include <stdio.h>
/* declaracin de prototipos */
/*Variable externa */
int numero;
void main ()
{
printf (Introduce el nmero: );
scanf (%d, &numero);
par_si_no ();
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 125 Funciones
negativo ();
}
void par_si_no ()
{
if ((numero % 2) = = 0)
{
printf (El nmero es par \n);
}
else
{
printf (El nmero es impar \n);
}
}
if (numero < 0)
{
printf (El nmero es negativo \n);
}
else
{
printf (El nmero es positivo \n);
}
}
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 126 Funciones
Supongamos que, tal y como mostramos a continuacin, queremos hacer un programa para visualizar
en pantalla la evaluacin de unos estudiantes
Juan
Marta
Pedro
Chapas
#include <stdio.h>
void linea (int);
void main ()
{
printf (Juan \t);
linea (27);
Cmo le pasamos valores a la funcin lnea encargada de dibujar la evaluacin del alumno?
Al definir una funcin la declaramos as: void linea (int puntos). Cuando se llama a la funcin la variable pun -
tos toma el valor entre parntesis de la llamada de la funcin (linea (10), por ejemplo), y utiliza ese valor en la
ejecucin de la funcin. En este caso la variable puntos toma el valor 10 al hacerse la primera llamada de la
funcin y ese es el valor que utiliza dentro de la funcin.
En este caso queremos obtener el mismo resultado pero la puntuacin de cada estudiante la tomaremos
del teclado siendo por tanto desconocida. Por lo tanto, en este caso no sabremos a priori cul es el
nmero que deberemos utilizar para dibujar la lnea. Cmo hacerlo? La informacin que le damos a la
funcin no es constante como en el caso anterior. Ahora, como puede observarse, se le pasa la variable
en la llamada a la funcin linea (datos), donde datos es la variable que contiene la informacin intro-
ducida mediante el teclado.
void main ()
{
int datos;
linea (datos);
}
main ( )
{ void linea (int puntos)
{
----- ------
-----
linea (datos) -------
------
----- -------
-----
} }
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 128 Funciones
Al hacer la llamada a la funcin, la variable datos toma el valor que tiene y de este modo se lo pasa a la
funcin linea. Dentro de esta funcin la variable puntos toma el valor pasado y las instrucciones del
cuerpo de la funcin utilizan ese valor.
En este caso se pasa tan solo una nica variable como argumento. Pero, como puede verse en el siguiente
ejemplo, tambin es posible pasar ms de una variable.
En este ejemplo dibujaremos una lnea mediante los caracteres introducidos desde el teclado. La longi-
tud de la lnea tambin ser un dato que pasaremos a la funcin. Para ello escribimos una funcin
dibuja que toma dos parmetros: el carcter y la longitud.
#include <stdio.h>
main ( )
void dibuja (char mi_carac, int mi_longitud)
{
{
-----
------
-----
-------
dibuja (carac, longitud)
------
-----
-------
-----
}
}
Como ya sabemos, las funciones dan resultados tomando un valor como argumento. Por ejemplo, la
funcin coseno cuando toma el valor 0 devuelve 1 (cos (0)=1).Cmo se realiza esto en lenguaje C?.
Las funciones dan como resultado de su ejecucin un valor mediante el uso de la sentencia return:
1. Primeramente , cuando se ejecuta return, el control del programa va al programa que ha lla-
mado a la funcin.
2. Posteriormente se evala la expresin entre parntesis que va despus de return, cuyo valor se
pasa como valor de la funcin.
La sentencia return puede ir en cualquier lugar de la funcin y tambin puede haber ms de una.
Supongamos que queremos escribir una funcin que calcula el logaritmo de un nmero. Para ello escri-
biremos un programa principal que pida el nmero y la base, luego llamaremos a la funcin logaritmo y
el programa principal visualizar el resultado.
#include <stdio.h>
#include <math.h>
return (log_valor);
}
Veamos otro ejemplo de utilizacin de funciones que devuelven un valor. Vamos a escribir un programa
que calcule el valor de la serie 1 + 22 + 33 + 44 + ...... + nn
#include <stdio.h>
#include <math.h>
clrscr ();
printf (Introduce el valor del lmite: );
scanf (%d, &limite);
return (valor);
}
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 131 Funciones
4.3. Punteros
Los punteros (en ingls pointer) expresan la direccin de una variable en la memoria. Para expresar la
direccin de una variable se utiliza el carcter &. Por lo tanto, si el nombre de la variable es puf , &puf
es el puntero de puf y tiene la direccin de puf. Claro que como ya sabemos, la direccin de una varia-
ble es un nmero constante y por lo tanto podemos decir que &puf es un puntero constante.
Pero en C tambin es posible definir variables puntero. Del mismo modo que una variable que tenga un
tipo de datos char, la cual toma un carcter como su valor, as una variable puntero toma como su valor
una direccin.
Pero cmo se declaran los punteros? En los ejemplos siguientes se declaran diversas variables tipo puntero:
int *i_ptr; fi variable puntero que admite direcciones de tipos de datos int, es decir, direcciones
de nmeros enteros.
char *c_ptr; fi variable puntero que admite direcciones de tipos de datos char, es decir, direccio-
nes de caracteres.
float *f_ptr; fi variable puntero que admite direcciones de tipos de datos float, es decir, direccio-
nes de nmeros reales.
Para declarar punteros, por lo tanto, es preciso declarar el tipo de dato del puntero:
int * i_ptr
el operador * (indireccin)
Como ya sabemos si ptr es una variable puntero su contenido ser una direccin. Mediante el operador *,
esto es *ptr, se consigue el valor contenido en esa direccin. En el ejemplo, se define una variable entera
denominada fermin y una variable puntero denominada fermin_ptr. Como se ve cada una de ellas tiene
asignada una direccin en memoria (fermin se encuentra en la 1000 y fermin_ptr en la 1004). Al realizar la
instruccin fermin = 22; el contenido de la direccin 1000 pasa a ser 22. Al realizar la asignacin fer -
min_ptr= &fermin; hacemos que la variable puntero fermin_ptr contenga la direccin de la variable fermin.
Por ltimo, al ejecutarse la instruccin valor = *fermn_ptr; el uso del operador indireccin posibilita el
recoger el valor almacenado en la direccin 1000 (que es el contenido de la variable fermin_ptr), en la
variable valor.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 132 Funciones
Ejemplo:
Nombre Direc. Cont.
int fermin;
fermin 1000 22
int *fermin_ptr; 1001
1002
fermin = 22; 1003
fermin_ptr 1004 1000
1005
fermin_ptr = &fermin; 1006
1007
valor 1008 22
valor = *fermin_ptr;
Es decir, al ejecutarse la sentencia valor = *fermin_ptr hacemos que se introduzca en la variable valor el
valor contenido en la posicin 1000, por consiguiente la variable valor toma el valor 22.
Supongamos que queremos crear un programa que reemplaza los contenidos de dos variables. Para ello
queremos definir una funcin. Esta funcin tomar como argumento estas dos variables y, despus de
ejecutarse, los contenidos de estas dos variables quedarn intercambiados.
#include <stdio.h>
void main ()
{
int x = 5, y = 10;
printf (Al principio x = %d e y = %d. \n, x, y);
elmio = *x_ptr;
*x_ptr = *y_ptr;
*y_ptr = elmio;
}
x 1010 5
1011
y 1012 10
1013
1014
De modo que,
Al principio x = 5 e y = 10.
A continuacin llamamos a la funcin cambiar_valores de este modo: cambiar_valores (&x, &y); Por lo
tanto los parmetros que toma la funcin cambiar_valores son las direcciones de x y de y.
Cuando ejecutamos la funcin cambiar_valores se declaran las variables puntero x_ptr e y_ptr . Al ser
x_ptr y y_ptr variables puntero de tipo entero, su contenido debe ser una direccin de nmero entero. A
continuacin se define tambin la variable elmio .
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 134 Funciones
x 1010 5
1011
y 1012 10
1013
x_ptr 1014 1010
1015
x_ptr = 1010 1016
y_ptr = 1012 1017
el operador * nos da el contenido de una direccin. y_ptr 1018 1012
1019
*x_ptr = 5
1020
*y_ptr = 10 1021
elmio 1022
De modo que despus de terminar la ejecucin de la funcin, la memoria queda de esta manera:
x 1010 10
1011
y 1012 5
1013
x_ptr 1014 1010
1015
1016
1017
y_ptr 1018 1012
1019
1020
1021
elmio 1022 5
Al volver nuevamente al programa main desaparecen todas las variables creadas durante la ejecucin de
la funcin. Cuando se ejecuta el segundo printf del programa principal, el valor de la variable x es 10 y
el de la variable y es 5. De modo que el resultado de la ejecucin del programa sera el siguiente:
Al principio x = 5 e y = 10.
Al final x = 10 e y = 5.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 135 Funciones
Ejemplo
#include <stdio.h>
#include <math.h>
Aunque en las anteriores secciones hemos examinado las variables que utiliza el lenguaje C y los tipos de
datos correspondientes, todava nos queda por examinar varias caractersticas de las variables. La ms
importantes son la duracin y su mbito de aplicacin (scope). Combinando estas dos caractersticas
el lenguaje C reconoce las diferentes maneras de guardar variables existentes.
La variable fija se crea al comienzo de un programa y permanece hasta el fin de la ejecucin de un pro-
grama manteniendo reservada su asignacin de memoria hasta la finalizacin del mismo.
La variable automtica en cambio est unida a una funcin o a un bloque en concreto del programa. De
modo que se crea en el momento en que esa funcin o ese bloque comienzan a ejecutarse y al terminar
la ejecucin desaparece.
En el lenguaje C es posible combinar la duracin y el mbito para definir las diferentes maneras de guar-
dar variables, las cuales son fundamentalmete cuatro y se indican mediante las siguientes palabras clave:
extern, static, auto, register.
Cuando se quiere utilizar una variable externa fuera del mdulo donde est definida, se vuelve a declarar
de nuevo, pero en este caso concretando por delante el indicador exter n. De esta forma, se indica que la
definicin de esta variable se ha hecho en algn otro lugar.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 137 Funciones
Estas variables tan solo se reconocen en los sitios en los que han sido definidas, pero no desaparecen al
terminar la ejecucin de la funcin. El ordenador mantiene sus valores para que se puedan volver a uti-
lizar si la funcin es llamada de nuevo.
Ejemplo,
En este ejemplo, vive es una variable esttica que es conocida nicamente en el mbito de aplicacin de
la funcin test_static. Sin embargo, el valor que almacena no se borra al terminar la ejecucin de dicha
funcin y es posible utilizar dicho valor en ejecuciones sucesivas de la funcin.
La diferencia entre las variables externas y las variables externas estticas reside en el mbito. Las varia-
bles externas son conocidas para todas las funciones. Las variables externas estticas tan slo se recono-
cen en los ficheros donde estn declaradas.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 138 Funciones
Fichero a Fichero b
En este ejemplo, suponemos que un fichero guarda las declaraciones y las funciones main () y figaro (). En
otro fichero se encuentran las otras dos funciones negro () y rojo (). La variable num (variable externa) es
conocida en todas las funciones y la variable numero (variable externa esttica) tan solo en las funciones
main y figaro.
Si en una funcin no se indica de otra manera todas las variables que declaramos son auto, y por lo tanto
no es obligatorio utilizar este indicador. Decimos que estas variables son automticas y se definen de esta
forma en su declaracin. Si se quiere puede utilizarse la palabra clave auto.
Generalmente las variables se guardan en la memoria RAM del ordenador. Podemos pedir para acelerar el pro-
ceso que las variables usadas frecuentemente se guarden en los registros de la CPU en vez de hacerlo en la
memoria. De esta forma puede acelerarse la ejecucin del programa. Tal y como se muestra en el siguiente
ejemplo, para ello se utiliza la palabra clave register:
A modo de resumen, en la siguiente tabla se muestran las diferentes maneras de guardar variables.
Escribir un programa utilizando N sumandos de la secuencia, que calcule cos (x). La cantidad N de
sumandos, ser equivalente al valor del ltimo y a la secuencia se aadirn los elementos necesarios
hasta que el ltimo (en valor absoluto) sea ms pequeo que 0.0005.
/ **************************************************************************************
Descripcin:
Este programa calcula el valor de la funcin coseno segn Taylor.
***********************************************************************************************/
#include <stdio.h>
#include <conio.h>
/* Limpia la pantalla */
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 140 Funciones
clrscr ();
valor_elemento = 1;
for (elemento = 1, cos = 1; valor_elemento > 0.0005; elemento ++)
{
if (elemento % 2 == 0)
{
signo = 1;
}
else
{
signo = -1;
}
cos += signo * valor_elemento;
}
/ **************************************************************************************
* Nombre de la funcin: potencia *
* *
* Argumentos de entrada *
* nmero: queremos calcular su potencia *
* exponente: lo que su nombre indica *
* Valor de salida *
* Esta funcin mediante return da el valor del nmero
elevado al exponente *
* *
* *
* Descripcin: *
* Esta funcin logra el nmero elevado al exponente *
* *
* *
***********************************************************************************************/
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 141 Funciones
/ **************************************************************************************
* Nombre de la funcin: factorial *
* *
* *
* Argumentos de entrada *
* nmero: queremos calcular su factorial *
* exponente: lo que su nombre indica *
* Valor de salida *
* Esta funcin mediante return calcula el factorial
del nmero *
* *
* *
* Descripcin: *
* Esta funcin calcula el factorial de un nmero *
* *
***********************************************************************************************/
float factorial (int num)
{
int cont;
float factorial;
7. Bibliografa
KERNIGHAN, BW., RITCHIE D.M. The C Programming Language. Ed. Prentice Hall.
PRESS, W.H., TEKOLSKY, S.A., VETTERLING, W.T., FLANNERY, B.P. Numerical Recipes in C. Ed. Cambridge
WAITE, M., PRATA, S., MA RT I N , D. Programacin en C. Introduccin y Conceptos Avanzados. Ed. Anaya
Multimedia.
Universidad del Pas Vasco / Euskal Herriko Unibertsitatea 143 Funciones
8. Ejercicios propuestos
Escribir un programa utilizando N sumandos de la secuencia, que calcule cos (x). La cantidad N de
sumandos, ser equivalente al valor del ltimo y a la secuencia se aadirn los elementos necesarios
hasta que el ltimo (en valor absoluto) sea ms pequeo que 0.0005.
Para realizar el programa, escribir dos funciones que calculen nmeros factoriales y hagan potencias.
2. Introducidos mediante el teclado los nmeros enteros A y B, escribir un programa que consiga el
mximo comn denominador (M.C.D.), siendo A B. He aqu el algoritmo de M.C.D. que se imple-
mentar en una funcin.
1. paso: haz DD = A y D = B.
2. paso: Calcula el resto de la divisin entre DD y D.
3. paso: Si el resto no es 0, haciendo DD = D y D = resto, vuelve al segundo paso.
4. paso: Si el resto es 0, el valor de M.C.D. es D.
3. El centro numrico es el nmero que divide en dos la lista de enteros. La suma de los enteros de
ambos lados es igual, y el comienzo de la primera lista es siempre 1.
De todos los enteros el primer centro numrico es el 6, el cual divide las listas (1, 2, 3, 4, 5) y (7, 8),
tal y como puede verse el resultado de la suma en ambas listas es 15 y el comienzo de la primera es
1. El segundo centro numrico es el 35, siendo las listas (1, 2, ..., 34) y (36, 37, .... , 49) y la suma de
cualquiera de ambas 595.
Mediante un programa encontrar los centros nmericos entre 1 y N. Para ello se utilizarn dos
funciones:
4. Se deja caer una pelota desde una altura H. La capacidad de hacer rebotes de la pelota se puede expre-
sar mediante un nmero R menor de 1.0. En cada rebote la altura que consigue la pelota es lo conse-
guido previamente multiplicado por R.
El programa nos pide el factor R para los rebotes y la altura de salida. Luego pedir la altura que
pueda conseguirse en cualquier rebote (mayor que cero); ms tarde calcular en qu rebote conse-
guir la pelota la altura establecida. Para ello el programa nos dir si la altura conseguida es menos o
mayor que lo ledo. Junto con esto, nos dir qu altura ha alcanzado la pelota en el ltimo rebote
NOTA: La altura de salida, conociendo el factor de rebote R y la cantidad de rebotes, debe ser escrita
en una funcin que calcule la altura conseguida en un rebote.
5. He aqu una conocida frmula de fsica nuclear para calcular la masa radioactiva que permanece des-
pus de pasados t aos.
M t = m * (1/2) t/h
Donde:
t es tiempo en aos
M t la masa que permanece pasados t aos
m la masa del comienzo
h media de vida, en aos
La media de vida para el istopo de Carbono 14 son 5.700 aos ; si la masa del comienzo es de 300 gra-
mos, dando diversos valores a t (t = 500, 1.000, 1.500, ..., 9.500, t = 10.000) mostrar en una tabla Mt.
Para ello dados diversos valores de t concretar en una funcin el valor de (1/2) t/h.