Está en la página 1de 12

Programación

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

1. Dominar cómo organizar un programa en funciones.


2. Conocer los elementos importantes dentro de una función.
3. Saber pasar parámetros por valor a una función.
4. Aprender cómo crear y utilizar las funciones en un programa

Bibliografía: Capítulo 5 Deitel. H. M. Cómo programar en C/C++. (LT) Tomo I, pág 148 – 171.

Estudio Independiente

Archivos de cabecera (header files) pág 159-160

Ejemplo : Un juego de azar pág 165-170

Recursión pág 171-181

Ejercicios para el Estudio Independiente

Autoevaluación pág 189-193

Ejercicios Propuestos pág 193 5.7, 5.8-5.10, 5.12-5.25, 5.31, 5.32,5.35-5.38

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.

Generalmente en la práctica, todo programador al implementar una aplicación, combina la utilización


de funciones conocidas (hasta ahora hemos utilizado las funciones printf, scanf, funciones
matemáticas, etc. todas de la biblioteca estándar) con la creación de nuevas funciones que el
programador escribe.
Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu

Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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

Formato de definición de una función

[Tipo de valor de regreso] NOMBRE_FUNCION ([Lista de parámetros sep. por comas])

Declaración de variables

Enunciados

[return [variable/expresión]]

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

Observaciones:

 El nombre de función es cualquier identificador válido


 El tipo de regreso es el tipo de dato del resultado regresado al que llama a la función.
 void– Tipo especial que indica que la función no devolverá VALOR. Al no especificar tipo el computador
asume int.
 La lista de parámetros consiste en una lista separada por comas que contiene las declaraciones de los
parámetros recibidos por la función al ser llamada. Si una función no recibe ningún valor, la lista de
parámetros es void.
 Debe especificarse para cada parámetro un tipo, a menos que sea int. Si no se especifica el compilador lo
asume int.
 Las declaraciones, junto con los enunciados dentro de las llaves forman el cuerpo de la función. También se
conoce como bloque de función.
 Bajo ninguna circunstancia puede ser definida una función dentro de la otra.
 Existen tres formas de regresar el control al punto desde el cual se invocó la función
o }
o return;
o return expresión;
 Todas las variables declaradas en las definiciones de funciones son variables locales
 Las variables que hemos declarado hasta ahora son locales a main()
 Concepto de variable LOCAL
 Generalización para cualquier bloque {}.
 Los parámetros de una función son variables locales.

Ejemplo 1:
Defina una función en C que permita evaluar la siguiente función matemática:

x2 ‐5 ; si x < 0

F(x) = x3 ‐2x2 ; si x ≤ 0 ≤ 10

4‐x/7 ; si x > 10

float f(float x) Preguntas necesarias para definir una función:


{ 1‐ ¿Qué recibe?
2‐ ¿Cuál es su nombre?
if (x < 0)
3‐ ¿Qué devuelve?
return x*x‐5;
Preguntas necesarias una vez definida la función
else if (x <= 10)
1‐ ¿Dónde la invoco (llamo)?
return x*x*x‐2*x*x; 2‐ ¿Cómo se invoca (llama)?
else
return 4‐x/7;
}

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

¿Dónde y de qué manera van ubicadas las funciones en un programa?


Las funciones en un programa principal constan de tres etapas: prototipo, llamada(invocación) y
definición (programación).
En C, antes de la función main, deben aparecer los prototipos de las funciones que el programador
va a definir en el propio fichero, de modo que estas funciones puedan ser utilizadas a partir de ese
momento. Después de la función main, debe aparecer la programación de las funciones cuyos
prototipos han sido declarados antes de main. Dentro del main o dentro de otras funciones previamente
declaradas, incluso dentro de ella misma (recursividad)va el llamado o invocación de la función.
Tanto en el prototipo como en el momento de la programación debemos declarar el tipo del valor que
retorna la función, el nombre de la función y la lista de parámetros de la función, ésta última entre
paréntesis. Si la función no tuviera parámetro dejaríamos vacía la lista de parámetros, como en main().

Ejemplo 2:
Obtener una tabla de valores de la función definida por tramos:

 2 x e 4x + 3 | x | + 1 si x<0

h ( x ) =  x2 - 5 x3 sen πx si 0≤x≤2

 x / ln(x) - 5 si x>2

y lograr la suma h(‐2) + h(‐1.5) + h(‐1) + … + h(2) + h(2.5) + h(3).



Reprogramaremos este ejemplo pero definiendo la función de programador H(x).
/* Fichero main.cpp */ 
#include <stdio.h> 
#include <math.h> 
 
float  H ( float x);  /* prototipo de la función*/ 
 
int main() 

    float x, h, Suma; 
    printf("%5s%10s\n","x","h(x)"); 
    for(Suma=0, x=‐2; x<=3; x+=0.5 ) { 
        h = H(x);    /* Llamado a la función H */ 
        printf("%5.2f%10.3f\n",x,h); 
        Suma+=h; 
    } 
    printf("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐\n"); 
    printf("%5s%10.3f\n","Suma",Suma); 
    return 0; 

 
Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu

Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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');
}

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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ú.

float f(float); void menu()


void menu(void); {
void limpieza(void);
printf("Escoja una opcion:\n");

printf("(1)‐Evaluar Funcion\n");
void main() {
char opcion; printf("(2)‐Salir\n");

do{ }
menu();

opcion = getch();
void limpieza() {
switch (opcion) {
float x; printf("Retorno para continuar ...");

case '1' : fflush(stdin);


printf("Introduzca x:"); getchar();
scanf("%f",&x);
system("cls");
printf("\n f(%f)=%f\n",x,f(x));
// clrscr();
limpieza();
break; }

case '2':
break;
default :
printf("Opcion incorrecta\n");
limpieza();
}
}while (opcion != '2');
}

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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.

2‐Generalización del alcance de las variables.

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?

Aquí resulta conveniente abordar las reglas de alcance de las variables


Reglas de alcance.

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.

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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:

#include <stdio.h> El programa de la izquierda imprimirá


void printx(void); x=0
int x = 0; x=1
int main()
{
int x= 1;
printx();
if ( x )
printf("x = %d\n",x);
return 0;
}

void printx(void)
{
printf("x = %d\n",x);
}

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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:

float H ( float x); /* prototipo de la función*/

El formato general de la definición del prototipo de una función es:


Tipo nombre (lista_de_parámetros) ;

El formato general de la definición de una función es:

Tipo nombre (lista_de_parámetros)


{
/* Declaraciones de variables */
/* Instrucciones */
}

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.

Si la función devuelve un resultado, entonces la expresión:


return Expresión
provoca la terminación de la función y devuelve el valor deseado.

Recuerde siempre que:


El prototipo de una función, el encabezado de esta y las llamadas a la misma deben todas estar
de acuerdo en cuanto al número, tipo y orden de los parámetros, así como en el valor de retorno.

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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));
}

/*implementación de la función mayor */


int mayor(int a, int b, int c)
{
int max = a; /*se asume que el primero es el mayor */
if (b > max)
max = b;
if (c > max)
max = c;
return max;
}

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

 auto: Son aquellas variables que se crean al comienzo de un bloque


 register: Registros de procesador. Se gana en eficiencia. Los compiladores modernos tratan de hacerlo
automáticamente
 extern y static: Se utilizan para declarar identificadores de variable y funciones de persistencia estática a
diferencia de las variables locales.

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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.

Ejemplo: imprimir los 5 primeros múltiplos y potencias de 4.

int a = 0; void multcuatro()


void multcuatro (void); {
void potcuatro(void); a +=4;
void main() { printf(“%d\n”,a );
int i; }
printf("|‐‐‐‐‐‐‐‐‐‐‐|\n");
printf("|multiplos 4|\n" ); void potcuatro()
printf("|‐‐‐‐‐‐‐‐‐‐‐|\n"); {
for(i=0; i<5; i++) static int b = 1;
multcuatro (); b *= 4;
printf("|‐‐‐‐‐‐‐‐‐‐‐|\n" ); printf(“%d\n”,b);
printf("|potencias 4|\n" ); }
printf("|‐‐‐‐‐‐‐‐‐‐‐|\n" );
for( i=0; i<5; i++)
potcuatro ();
printf("|‐‐‐‐‐‐‐‐‐‐‐|\n" );
fflush(stdin);
getchar();
}

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.

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu



Programación I
                           “El secreto de una vida exitosa es encontrar cuál es tu destino y entonces perseguirlo.”

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.

Dpto. Automática, FIAB Ybrain Hernández López ybra@automatica.cujae.edu.cu

También podría gustarte