introducción a las funciones en lenguaje c
DESCRIPTION
Este material describe basicamente el uso de las funciones en lenguaje cTRANSCRIPT
Introducción La Programación Estructurada pretende evitar la
edición de programas en un solo bloque (monolíticos), dificiles de manejar por su longitud. Algunos autores aconsejan que el cuerpo de una función debería ser visible en una sola pantalla.
La Programación Estructurada es una estrategia de resolución de problemas y una metodología de programación que incluye dos grandes líneas:
• El control de flujo en un programa debería ser tan
simple como fuera posible. • La construcción de un programa debería hacerse
empleando la técnica del diseño descendente (top-down).
2
Prof. Omar Rosales
Diseño Top-down.
El método de diseño Top-Down, también llamado método de refinamientos sucesivos o divide y vencerás, consiste en descomponer repetidamente un problema en problemas más pequeños. Es decir:
– Construir un programa a partir de pequeñas piezas o
componentes.
• Esas pequeñas piezas son llamadas módulos.
– Cada pieza es más manejable que el programa original
3 Prof. Omar Rosales
Programando Módulos en C
• Funciones; – Módulos en C. – Los programas combinan funciones definidas por el
usuario (funciones de usuario) con funciones de librería. • Las librerías estandar de C contienen una amplísima colección de
funciones generales y específicas.
• Llamadas a funciones: – Invocar a funciones:
• Mediante su nombre y argumentos (datos sobre los que actuar) • Pueden devolver resultados.
– Analogía de la llamada a una función: • En un empresa el jefe encarga una labor al trabajador.
– El trabajador busca la información, hace el trabajo y devuelve un resultado.
– La información ha permanecido oculta: el jefe desconoce los detalles.
4 Prof. Omar Rosales
Funciones de la librería math.h
• Funciones de math.h: – Se emplean en cálculos matemáticos – #include <math.h>
• Formato de la llamada a la función: – NombreFuncion( argumento/s ); – y = sqrt( 900.0 ); //llamada
• La llamada, emplea un argumento (900.0) sobre el que actúa, devolviendo su raiz cuadrada, que se guarda en la variable y
• Si lleva más de un argumento, se separan mediante comas (,): z = pow(base, exponente); • Las funciones de math.h devuelven valores de tipo double
– Los argumentos pueden ser constantes, variables o expresiones.
5
Prof. Omar
Rosales
Algunas funciones disponibles en math.h
6
Funcion: Devolución:
int abs(int num) Valor absoluto de un entero.
double fabs(double num) Valor el valor absoluto de un
argumento de doble precisión (double)
double pow(double x,double y) El valor x elevado a y.
int rand(void) Número aleatorio.
double sin(double angle) El seno de un ángulo (angulo en
radianes).
double cos(double angle) El coseno de un ángulo en radianes.
double sqrt(double num) Raiz cuadrada de num.
double log (double val) Logaritmo neperiano de val
double log10 (double num) Logaritmo en base 10 de num
double ceil (double num); El entero más pequeño de un decimal
double floor (double num); El entero inmediato superior a un
decimal
Prof. Omar
Rosales
Utilización de funciones de librería
• Calcular la raiz cuadrada de (x1 - x2)2 + (y1 - y2)2
a = x1 – x2;
b = y1 – y2;
c = pow(a,2) + pow(b, 2);
d = sqrt(d);
O bien:
d = sqrt(pow((x1-x2),2) + pow((y1-y2),2));
7
Prof. Omar
Rosales
Funciones Realmente al llegar a este punto, tod@s hemos escrito nuestras propias
funciones y usado funciones de librería::
– main() es una función que debe existir en todo programa en C: Función principal
– printf(), scanf() son funciones de librería que hemos utilizado muchísimas veces en nuestros programas. Su definición se encuentra en las librerías de cabecera xxx.h
– mi_función()es una función de usuario, creada por mi, cuyo código editaré yo.
Para utilizar funciones no declaradas en las xxx.h es necesario hacer dos cosas:
– Crear las funciones. – Llamar a las funciones (invocación, evocación de la
función).
8
Prof. Omar
Rosales
Declaración de funciones
9
La definición de una función es como sigue:
{
declaraciones…
sentencias…
}
tipo_devuelto - es el tipo del dato que devuelve la función.
• void – indica que la función no devuelve valor.
nombre_funcion – cualquier identificador válido.
lista de parámetros formales – describe el tipo y el
nombre de los argumentos que se le pasan a la función cuando es
invocada, separados por comas, para que actúe sobre ellos.
tipo_devuelto nombre_funcion(lista parámetros formales)
Protipo de función
Cuerpo de la función
Prof. Omar
Rosales
Ejemplo
• Definimos la función que eleva al cubo un número:
int cubo(int num)
{
int resultado;
resultado = num * num * num;
return resultado;
}
• Esta función puede ser llamada como:
n = cubo(5);
O bien:
printf(“El cubo de %d es %d”, n, cubo(5));
10
Prof. Omar
Rosales
Prototipos de Función
• Función prototipo: – Nombre de la función. – Parámetros que la función va a utilizar. – Tipo de dato devuelto: tipo del dato que la función
devuelve mediante return (por defecto es int)
• La función prototipo sólo es necesaria si su definición (cuerpo de la función) se encuentra en otro lugar (por ejemplo después de main())
• La función de prototipo: int maximo( int, int, int );
• Toma tres enteros • Devuelve un entero
11
Prof. Omar
Rosales
12
#include <stdio.h>
#include <conio.h>
int maximo( int, int, int ); /* funcion prototipo */
int main()
{
int a, b, c;
printf( "Intro tres enteros:\n " );
scanf( "%d%d%d", &a, &b, &c );
printf( "El maximo es: %d\n", maximo( a, b, c ) );
getch();
return 0;
}
/* Definición, cuerpo de la funcion maximo */
int maximo(int x, int y, int z)
{
int max = x;
if ( y > max )
max = y;
if ( z > max )
max = z;
return max;
}
Ver f3.cpp
Prof. Omar
Rosales
13
int main()
{
int a, b, c;
printf( "Intro tres enteros:\n " );
scanf( "%d%d%d", &a, &b, &c );
printf( "El maximo es: %d\n", maximo( a, b, c ) );
getch();
return 0;
}
f4.cpp
//declaración y cuerpo de la funcion
int maximo( int x, int y , int z)
{
int max = x;
if ( y > max )
max = y;
if ( z > max )
max = z;
return max;
}
#include <stdio.h>
#include <conio.h>
Ver f5.cpp
Prof. Omar
Rosales
Estilos en la definición y utilización de funciones
14
#include <stdio.h>
int max(int,int); //prototipos
int min(int,int);
int main(void)
{
min(x,y);
max(u,v);
..
}
int max (int a, int b) //cuerpo
{
….
}
int min (int a, int b)
{
….
}
#include <stdio.h>
int max (int a, int b)
{
….
}
int min (int a, int b)
{
….
}
int main(void)
{
..
min(x,y);
max(u,v);
..
}
Llamada a la Función
• Un programa consta de una o más funciones, una de las cuales debe ser la función principal main( ).
• Cuando un programa encuentra nombre elde una función, la función es llamada o invocada.
• Cuando la función “finaliza su trabajo”, el control del programa es devuelto al entorno desde donde fue invocada, continuando allí la ejecución del programa.
15
main()
func1
func2
Prof. Omar
Rosales
16
#include <stdio.h>
void mensaje(void); // prototipo de función
// o función prototipo
int main (void)
{
mensaje( ); /* Llamada a la función*/
return 0;
}
void mensaje(void) /*Definición, cuerpo de la función*/
{
printf(“Un mensaje para tí,\n”);
printf(“desde la funcion\n”);
}
Significado: void mensaje(void);
No devuelve nada.
No recibe argumentos para operar
Ejemplo de función
Prof. Omar
Rosales
Tipos de variables según la visibilidad
Las variables en C se pueden clasificar de varias formas, pero atendiendo a la parte del código que puede acceder a ellas se clasifican en:
- Variables Globales: son accesibles desde cualquier lugar del código (tanto desde main() como desde las funciones.
- Variables Locales: son accesibles desde la función en que son declaradas. Invisibles para otras funciones.
La declaración de las variables globales ha de hacerse antes de la función main()
La declaracion de las variables locales se hará en el cuerpo cada función.
Veamos un ejemplo:
17
Prof. Omar
Rosales
#include <...>
//void funcion(void); //prototipo de funcion
//Declaración de variables GLOBALES:
int numero = 5;
float valor = 12.3;
char *c = “Hola”;
int main()
{
int posicion //local a main
...
funcion(); //Llamada a la función
printf(“%d”, resultado);
...
}
void funcion(void)
{
int posicion; //local a funcion()
int resultado //local a funcion()
resultado = (int)(numero + valor);
}
18
Variables Globales
Son variable distintas
Prof. Omar
Rosales
19
/* ejemplo de variables locales*/
#include <stdio.h>
#include <conio.h>
void func1 (void);
int main (void)
{
int i = 5; //local a main()
printf("En main(): %d \n", i);
func1( );
printf("\nDe nuevo en main(): %d \n",i);
getch();
return 0;
}
void func1 (void)
{
int i = 6; //local a func1
printf("\nEn la funcion: %d\n", i);
i++;
printf("\nEn la funcion i++: %d\n", i);
} Prof. Omar
Rosales
Reglas de visibilidad (scope rules)-I
Variables locales: • Son las que se declaran dentro de una función. Están ocultas a otras
funciones. • Se crean al iniciarse la ejecución de la función en que se encuentran
declaradas y se destruyen al salir de la función • Variables con el mismo nombre locales en dos funciones, son variables
diferentes. int funcion1(...) {
int x = 1, y = 2, m = 3, n = 4;
. . .
}
int funcion2(...)
{
int x = 1, y = 2, m = 3, n = 4;
. . .
}
20
x, y, m, n son variables
diferentes, en las mismas
direcciones de memoria
(no simultáneamente)
local.cpp
local2.cpp
Prof. Omar
Rosales
Reglas de visibilidad (scope rules)-II
Variables globales: • Una variable es global cuando es declarada fuera de
cualquier función. • Son visibles desde cualquier lugar del programa y se
pueden utilizar en cualquier sitio. • Si dentro de una función se vuelve a declarar, de modo
local, una variable global, dentro de la función se utilizará la variable local.
• Al ser visibles desde cualquier lugar, pueden ser alteradas de modo local de forma no deseada: efecto lateral.
• Una variable global no debe ser enviada como argumento a una función.
21
Ver global.cpp y global_local.cpp
La sentencia return
• Si una función debe devolver algo, lo hace mendiante la sentencia return.
• Cuando se ejecuta la instrucción return, el control del programa es devuelto inmediatamente al entorno de la llamada.
• Si a la instrucción return le sigue una expresión , el valor de esa expresión será devuelto al lugar de llamada de la función.
• Si una función es declarada sin tipo a devolver, por defecto devolverá un valor int:
main() //devolverá un entero
• Una instrucción return tendrá una de las siguientes formas: return;
return expresion; return 0;
22
Prof. Omar
Rosales
Ejemplos de return
23
return; //Devuelve el control del programa. // No devuelve valor
return 77; //Devuelve el control del programa //y un valor
return ++a; //Devuelve el control del programa //y un valor
return (a+b+c); //Devuelve el control del programa //y el valor de (a+b+c)
Hay que tener cuenta que cualquier instrucción que vaya detrás
de return no será ejecutada (ya que el flujo del programa es
transferido al lugar de la llamada a la función).
Prof. Omar Rosales
24
#include <stdio.h>
#include <conio.h>
int min (int a, int b);
int main (void)
{
int j, k, m;
printf(“\nIntro dos enteros: ");
scanf("%d %d", &j, &k);
m = min(j, k);
printf("\nEl minimo es: %d\n", m);
getch();
return 0;
printf("\nFin de programa"); //Codigo inancanzable
}
int min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
Prof. Omar
Rosales
Parámetros, argumentos • Una función puede ser llamada con cero o
más argumentos. • En el prototipo de función: int func(int x, double y, char c);
• En la llamada a la función: valor = func(edad, puntuacion, letra);
25
La lista de parámetros formales
(variables y sus tipos)es
declarada aquí
Lista de parámetros
actuales (sin su tipo): Prof. Omar Rosales
Normas para escribir la lista de argumentos formales
• El número de parámetros formales y actuales debe ser coincidente.
• La asociación de argumentos es posicional: el primer parametro actual se corresponde con el primer parámetro formal, el segundo con el segundo, etc…
• Los parámetros actuales y formales deben ser tipos de datos compatibles.
• Los argumentos actuales pueden ser variables, constantes o cualquier expresión del tipo de dato correspondiente al parámetro formal.
• Las llamadas pueden ser por valor o por referencia
26
Prof. Omar
Rosales
27
#include <stdio.h>
void imprime_mensaje (int k); /*funcion prototipo */
int main (void) {
int n;
printf(“Tengo un mensaje para tí.\n”);
printf(“¿Cuantas veces quieres verlo? ”);
scanf(“%d”, &n);
imprime_mensaje(n);
return 0;
}
void imprime_mensaje(int k) /* definición de funcion */
{
int i;
printf(“\nEste es tu mensaje:\n”);
for (i=0; i < k; ++i)
printf(“En el fondo del mar…\n”);
}
Parámetros, argumentos formales
Parámetros, argumentos actuales
Prof. Omar
Rosales
Paso de parámetros por valor
• Cada argumento es evaluado, y su valor es usado
localmente en el lugar del correspondiente parámetro formal.
• Si se pasa una variable a una función, el valor de esta variable almacenado en el entorno de la llamada no cambia. (la variable transferida si es alterada en la funcion llamada, no afecta al valor original
• Al llamar por valor, el valor de la variable que queremos transferir es copiado en el parámetro actual.
• Ver: por_valor.cpp
28
Prof. Omar
Rosales
29
#include <stdio.h>
int sumar (int n);
int main (void)
{
int n, resultado;
n = 3;
printf(“%d\n”, n);
resultado = sumar(n);
printf(“%d\n”,n);
printf(“%d\n”,resultado);
return 0;
}
int sumar(int x)
{
int sum=0;
for ( ; x > 0; --x)
sum += x;
printf(“%d\n”, x);
return sum;
}
3
0
3
6
Ver f2.cpp
Prof. Omar
Rosales
Corrige los errores en los siguientes fragmentos de programa
30
1. int g (void)
{
printf (“Función interna\n”);
int h(void)
{
printf(“Funcion interna h\n”);
}
}
2. int sum(int x, int y)
{
int resultado;
resultado = x + y;
}
La función h() no
es correcta. LAS
FUNCIONES NO
PUEDEN SER
ANIDADAS
La función debe
devolver un valor
int
Prof. Omar
Rosales
Corrige los errores en los siguientes fragmentos de programa
31
3. void f (float a);
{
float a;
printf (“%f”, a);
}
4. void producto (void)
{
int a, b, c, resultado;
printf(“Intro 3 enteros: ”);
scanf(“%d %d %d”, &a, &b, &c);
resultado = a * b * c;
printf(“El resultado es %d\n”, resultado);
return result;
} Prof. Omar
Rosales
32
#include <conio.h>
#include <stdio.h>
void f(float a);
void main()
{
float z=25;
f(z);
printf("\nEl valor de z en main() no cambia: %g", z);
getch();
}
void f(float z)
{
z += 100;
printf (“En la funcion imprimimos; %g", z);
}
Ver f1.cpp
Prof. Omar
Rosales
Paso de parámetros por referencia (por dirección)
• Cuando a una función se le pasa un parámetro por referencia, lo que se hace es enviar a la función la dirección de memoria de la variable.
• La función puede modificar el valor de la variable pasada por referencia (se le pasa la dirección de memoria, se modifica el contenido y se almacena en el misma dirección, con lo que se trata de la misma variable)
• Al pasar un variable por referencia, la variable debe ir precedida por el operador &.
• Se pueden pasar punteros como argumentos, método empleado para la transferencia de arrays.
33
Ver seriefpun.cpp
Prof. Omar
Rosales
Paso de parámetros por referencia (por dirección)
La declaración: int funcion(char *car, int &p);
indica una función que devuelve un valor entero y recibe dos argumentos: un puntero *car y la dirección de memoria &p de una variable.
char *funcion(char *p, int y);
función que recibe un puntero a carácter y un entero, devolviendo un puntero a carácter. El puntero que recibe y devuelve puede ser a un simple carácter o a una cadena de caracteres (en este caso puede requerir su inicialización como cadena o la realización de una reserva dinámica de memoria en función del tamaño deseado).
34
matf1.cpp cadcat.cpp matbi.cpp matf2.cpp
Paso de parámetros por referencia (por dirección)
• Si en lugar de arrays monodimensionales (vectores y/o cadenas de caracteres), pretendemos pasar como argumentos arrays de dos a ó mas dimensiones, el asunto se complica, aunque se utiliza la misma técnica del paso por referencia. Emplearemos declaraciones como:
void funcion(int array[][5]); recibe un array indeterminado ([ ] vacío).
void funcion(int array[][2][3]); idem pero tridimensional.
Ver: intbidim.cpp intridim.cpp por_referencia.cpp charff.cpp charff2.cpp charff3.cpp
35
Prof. Omar
Rosales
Recursividad
• Dado que una función puede llamar a otras funciones, en C está permitido que una función pueda llamarse a sí misma. Esta propiedad recibe el nombre de recursividad.
• Como la función es llamada con argumento, este debe cambiar para evitar caer en un bucle infinito.
• La recursividad se emplea frecuentemente en problemas de calculo factorial y potencias, pero es ineficaz en problemas que pueden resolverse mediante bucles (la recursividad consume mucha memoria, creando nuevas copias de los argumentos en cada una de las llamadas)
36
Ver recursiv.cpp
Ver recursi1.cpp Ver recursi2.cpp Ver potrecusiv.cpp