Documentos de Académico
Documentos de Profesional
Documentos de Cultura
I
“El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”
Tema 3 Modularización
Conferencia 03 Funciones.
Sumario:
1. Concepto de función.
1.1. Declaración, definición y llamado de funciones.
1.2. Argumentos (parámetros) y valores de retorno.
2. Reglas de alcance (ámbito) de las variables.
Objetivos
Estudio Independiente
Introducción
Hasta ahora se ha visto como realizar un programa simple en C. Sin embargo, la mayoría de las
aplicaciones que resuelven problemas prácticos son mucho mayores y más complejas. La práctica ha
demostrado que la mejor manera de enfrentar un problema complejo es dividiéndolo en pequeños sub-
problemas o módulos que sean más fáciles de manipular. Para poder llevar a cabo esta filosofía de
trabajo en C tenemos las funciones. Las funciones son estos pequeños módulos que pueden ser
conectados formando una aplicación más compleja.
Programas grandes
Divide y vencerás
Módulos ( en C‐> funciones)
o Funciones
Biblioteca estándar
Definidas por el usuario
Los enunciados para definir una función se escriben una sola vez y una vez hecho esto, las funciones
se ejecutan a través de un llamado a función.
Para realizar un llamado a función se especifica el nombre de la misma así como los elementos que
necesita esta para realizar su operación (parámetros).
Las funciones se invocan mediante llamada a función
Nombre de la misma
Se les proporciona información a través de los argumentos, para que pueda realizar su tarea.
Ejemplo:
main
scanf…
Quien llama a una función no conoce cómo esta realiza su tarea, solo conoce que la necesita para realizar
determinada tarea y lo que devuelve esta (en caso de que devuelva algún resultado).
Las funciones se pueden encadenar F1‐>F2‐>F3 sin embargo F1 no conoce que F2 invoca a F3 para realizar su
tarea.
Las funciones permiten al programador modular un programa:
Ventajas:
El programa es más manipulable.
Reutilización de software.
Evitar repetición de código.
El tiempo de diseño se acorta.
Depuración de código
Declaración de variables
Enunciados
[return [variable/expresión]]
Observaciones:
x2 ‐5 ; si x < 0
F(x) = x3 ‐2x2 ; si x ≤ 0 ≤ 10
4‐x/7 ; si x > 10
h ( x ) = x2 - 5 x3 sen πx si 0≤x≤2
x / ln(x) - 5 si x>2
float H (float x) /* Programación de la función H */
{
float h;
if (x<0)
h = 2*x*exp(4*x)+3*fabs(x)+1;
else
if (x<=2)
h = pow(x,2)‐5*pow(x,3)*sin(M_PI*x);
else
h = 5/log(x)‐5;
return h;
}
Observe además que la declaración del prototipo termina con;. En el prototipo no es necesario especificar el
identificador de los parámetros, es decir, podíamos haber declarado el prototipo así:
float H ( float ); /* prototipo de la función*/
Por otra parte, al programar la función, en el encabezamiento de la función, no ponemos el punto y coma al final
del encabezamiento y es obligatorio declarar los identificadores de los parámetros que vamos a utilizar.
Ejemplo 3:
Escriba un programa principal donde existan dos opciones de menú (evaluar función y salir de programa).
float f(float);
void main()
{
char opcion;
do{
printf("escoja una opcion:\n");
printf("1‐Ejecutar Funcion\n");
printf("2‐Salir\n");
opcion = getch();
switch (opcion) {
case '1' :
float x;
printf("Introduzca x:");
scanf("%f",&x);
printf("\n f(%f)=%f\n", x,f(x));
break;
case '2':
break;
default :
printf("Opcion incorrecta\n");
}
printf("Retorno para continuar ...");
fflush(stdin);
getchar();
system("cls");//clrscr();
}while (opcion != '2');
}
Observaciones:
- Problema: si el usuario presiona 2 para salir se ejecutan printf,flush,getchar,clrscr. Esto no es lógico, para
resolver este problema deberíamos repetir este código en los casos 1 y 2.
- Sin embargo, ahora podríamos construir una función que incluyera el código repetido y en su lugar invocar
a la función.
- También pudiéramos hacer otra para presentar el menú.
do{ }
menu();
opcion = getch();
void limpieza() {
switch (opcion) {
float x; printf("Retorno para continuar ...");
case '2':
break;
default :
printf("Opcion incorrecta\n");
limpieza();
}
}while (opcion != '2');
}
Observaciones:
1. Prototipo de funciones: Indica al compilador el tipo de dato regresado por la función, el número de
parámetros que la función espera recibir, los tipos de dichos parámetros y el orden en que se esperan los
mismos.
2. float x: Se declara como local a la estructura swicth, la variable tiene vida únicamente dentro de la
estructura.
3. Cuando se invoca la función float f(float) se crea otra variable x que es local a la función f y se destruye al
finalizar la llamada a la función.
4. Esto se denomina paso de parámetros por valor y se copia el valor de una en la otra.
Retomando el ejemplo 2
Observe que en el programa anterior hemos declarado una variable llamada h, tanto en la función main como
en la función H, mientras que también hemos declarado una variable llamada x tanto en la función main como
en la lista de parámetros de la función H y de su prototipo.
¿Existirá alguna relación entre estas variables que tienen el mismo nombre y aparecen declaradas en diferentes
lugares?
Hasta ahora hemos visto que toda variable cuando se declara posee 4 atributos: nombre (identificador), tipo,
valor y una dirección de memoria.
Sin embargo, los identificadores de las variables tienen también otros atributos que incluyen: clase de
almacenamiento, duración de almacenamiento y alcance.
La clase de almacenamiento de una variable determina cuál de las partes del programa puede acceder a ella y
cuánto tiempo dura su existencia. Existen cuatro clases de almacenamiento: automáticas, externas, estáticas y
registro.
La duración de almacenamiento es el período durante el cual dicho identificador existe en memoria. Algunos
identificadores tienen una existencia breve, otros son creados y destruidos en forma repetida y otros existen
durante toda la ejecución de un programa.
El alcance es la porción del programa en el cual dicho identificador puede ser referenciado. Por ejemplo, cuando
en un bloque declaramos una variable, esta puede ser referenciada solo en dicho bloque o en los bloques
anidados dentro de dicho bloque.
Los cuatro alcances posibles para un identificador son:
de función,
de archivo,
de bloque
de prototipo de función.
Un identificador declarado como parámetro de una función, como por ejemplo, la x en la programación de la
función H, tiene alcance en todo el bloque de la función H.
float H (float x) /* Programación de la función H */
{
float h;
if (x<0)
h=x+5;
else
h = 5/log(x)‐5;
return h;
}
Un identificador declarado fuera de toda función tiene alcance de archivo. Por tanto, es conocido por todas las
funciones a partir del punto donde está declarado y hasta el final del archivo. Las variables globales, los
identificadores de función y los prototipos de función tienen alcance de archivo.
Cuando una variable es declarada fuera de una función (alcance de archivo), se puede usar a partir del momento
en que ha sido declarada hasta el final del archivo o fichero en que la hemos declarado. En el ejemplo, la función
H tiene alcance de archivo, lo cual se asegura con la declaración de su prototipo al inicio del fichero.
Los identificadores de bloque son los que están definidos dentro de un bloque (limitado por { }). Las variables
locales declaradas al principio de cualquier función, así como los parámetros de función, tienen alcance de
bloque. Cualquier bloque puede tener declaraciones de variables (siempre al principio del bloque en C).
En el ejemplo 2, las variables x y h declaradas en las funciones main y H respectivamente no tienen ninguna
relación entre sí, ellas solo pueden ser referenciadas dentro del bloque de la función en las que han sido
declaradas. Por ello no es necesario darles nombre diferente, puesto que son independientes entre sí.
Cuando los bloques están anidados, y un identificador de un bloque externo tiene el mismo nombre de un
identificador de un bloque interno, el identificador “externo” será “ocultado” hasta que el bloque interno termine.
Veamos un ejemplo de esto:
void printx(void)
{
printf("x = %d\n",x);
}
Los identificadores con alcance de prototipo son aquellos que se utilizan en la lista de parámetros del prototipo
de una función. Note que los prototipos de función no requieren de nombres en la lista de parámetros, solo
requieren de tipo. Si en la lista de parámetros de un prototipo de función se utiliza un nombre, este será ignorado
por el compilador. Como, por ejemplo, la x en:
El nombre de la función es cualquier identificador (recuerde que los identificadores comienzan por
una letra y no permiten espacios sino caracteres de subrayado _ )
El Tipo es el tipo de datos del resultado del valor que regresa o devuelve la función al ser llamada.
El tipo de valor de retorno o regreso void indica que una función no devolverá valor. Un tipo de valor
de regreso no especificado será asumido por el compilador como int.
La lista_de_parámetros consiste en una lista, separada por comas, que contiene las declaraciones
de los parámetros recibidas por la función al ser llamada. Si una función no necesita recibir ningún
parámetro; la lista de parámetros es void (En el lenguaje C o vacía en C/C++).
Para cada parámetro debe ser indicado el tipo de datos. No se puede declarar una función dentro
de la declaración de otra.
Se debe tener en cuenta cuando se está programando que cada función debe limitarse a ejecutar una sola tarea
sencilla y bien definida. Si la tarea a realizar es muy compleja, se puede dividir en varias funciones.
A continuación veremos otro ejemplo de un programa que luego de recibir 3 números enteros introducidos por
el usuario, muestre en pantalla el mayor de ellos.
Para realizar este programa utilizando funciones se puede definir una función que reciba como parámetros 3
enteros y devuelva el mayor de ellos como resultado. Esto quedaría de la siguiente forma:
#include <stdio.h>
int mayor(int a, int b, int c); /*prototipo de la function mayor*/
void main() {
int x, y, z;
printf("Introduzca los tres numeros: ");
scanf("%d%d%d",&x, &y, &z);
printf("\nEl mayor de los valores introducidos es: %d", mayor(x,y,z));
}
Como se ve, la función main solamente recibe los valores ingresados por el usuario, pero no realiza la operación
de seleccionar el mayor, en su lugar toma estos valores entrados por el usuario y se los pasa como argumentos
a la función mayor que dados tres números sabe devolver el mayor de ellos y este valor de retorno lo recibe
nuevamente la función main y lo muestra a través de la función printf.
Nótese que la función mayor es independiente de la entrada de datos por teclado. Esta función no conoce
el origen de los datos, simplemente recibe 3 valores pasados como argumentos en su lista de parámetros,
realiza la acción de seleccionar el mayor de ellos y este resultado lo devuelve a quien la llamó (en este caso la
función main).
Clase de almacenamiento (pag 168, Cap 5)
C proporciona 4 clases de almacenamiento
En el caso de las variables extern no es necesario usar la palabra reservada, con declarar una variable fuera de
cualquier función, incluso de main, estamos declarando una variable global. Esto quiere decir que esta variable se
puede acceder por cualquiera de las funciones definidas en nuestro programa sin necesidad de declararlas. Estas
siempre se inicializan a 0.
Las variables static, son variables que se declaran dentro de una función y que solo puede ser accedidas dentro de
la misma. Se diferencian de las variables locales en que estas no se crean y destruyen en cada llamada a función.
OBSERVACIONES IMPORTANTES
Resaltar la necesidad de que la variable a sea global de esta forma pueden acceder a ellas todas las funciones del
programa, incluyendo la función principal. No se debe abusar del uso de variables globales pues estarían cargadas
en memoria todo el tiempo que se ejecute el programa.
Destacar la variable static int b pues cada vez que se ejecute la función mantiene el valor, (no se crea ni se destruye
con cada llamada a función como sí lo hacen las variables locales).
Conclusiones
Como se ha visto, la programación organizada en funciones permite dar más claridad al código
generado siendo más fácil de manipular a la vez que permite la reutilización de código evitando escribir
segmentos de programa más de una vez pues esta repetición se sustituye por el llamado a la función.
Se ha aprendido cómo declarar una función, sus principales elementos, así como la forma de realizar
el llamado a una función desde otra.
Otro aspecto importante visto en esta conferencia es el alcance de los identificadores de variable o de
función.