Upload
aisha
View
83
Download
0
Embed Size (px)
DESCRIPTION
Funciones. CONTENIDO Consideraciones sobre funciones Estructura de un programa en C Uso de funciones Paso de parámetros Punteros Ejemplo. Funciones. Todo programa C está construido en base a funciones. - PowerPoint PPT Presentation
Citation preview
Curso 04-05. Práctica 3 1
Funciones
CONTENIDOConsideraciones sobre funciones
Estructura de un programa en C
Uso de funciones
Paso de parámetros
Punteros
Ejemplo
Curso 04-05. Práctica 3 2
Funciones
Todo programa C está construido en base a funciones.
Las funciones permiten estructurar la codificación de los programas reduciendo su complejidad y como consecuencia, mejorando la eficiencia de su desarrollo.
Las funciones permiten la reutilización de código.
La subdivisión de un programa en varias funciones dependerá, en general, del número de tareas independientes y/o del número de veces que se repita o pueda repetirse una tarea.
Curso 04-05. Práctica 3 3
Funciones
Las funciones pueden devolver un valor.
Si no devuelve nada se declara de tipo void.
Si devuelve un valor, la función se declara del tipo de dato que coincide con el tipo del valor que se devuelve. (se verá más adelante).
Con independencia del número de funciones en que se descomponga un programa siempre debe existir una y sólo una función que se llame main( ), ya que cualquier programa C empieza ejecutándose por la citada función main().
En este curso declararemos a la función main() de tipo void.
Curso 04-05. Práctica 3 4
Funciones
Estructura general de un programa C en IP1definiciones y declaracionesvoid main (void){ declaración de variables instrucciones}tipo1 nombre_función1 (tipo11 arg11, tipo12 arg12, ...){ declaración de variables instrucciones}tipo2 nombre_función2 (tipo21 arg21, tipo22 arg22, ...)
...tipoN nombre_funciónN (tipoN1 argN1, tipoN2 argN2, ...){ declaración de variables instrucciones}
definiciones y declaracionesvoid main (void){ declaración de variables instrucciones}tipo1 nombre_función1 (tipo11 arg11, tipo12 arg12, ...){ declaración de variables instrucciones}tipo2 nombre_función2 (tipo21 arg21, tipo22 arg22, ...)
...tipoN nombre_funciónN (tipoN1 argN1, tipoN2 argN2, ...){ declaración de variables instrucciones}
tipo1 nombre_función1 (tipo11, tipo12, ...);tipo2 nombre_función2 (tipo21, tipo22, ...);
...tipoN nombre_funciónN (tipoN1, tipoN2, ...);
tipo1 nombre_función1 (tipo11, tipo12, ...);tipo2 nombre_función2 (tipo21, tipo22, ...);
...tipoN nombre_funciónN (tipoN1, tipoN2, ...);
Curso 04-05. Práctica 3 5
Funciones
LEAfunc nombre (e1:T1; ...; en:Tn) dev (r:Tr)Pre: {P(e1, e2, ..., en)}Post: {Q(e1, e2, ..., en, r)}cons definición de constantesvar declaración de variablesprin sentenciasfin
LEAfunc nombre (e1:T1; ...; en:Tn) dev (r:Tr)Pre: {P(e1, e2, ..., en)}Post: {Q(e1, e2, ..., en, r)}cons definición de constantesvar declaración de variablesprin sentenciasfin
CTr nombre (T1 e1, ..., Tn en){ Tr r; declaración de variables
instrucciones
return r;}
CTr nombre (T1 e1, ..., Tn en){ Tr r; declaración de variables
instrucciones
return r;}
Definición de Función: (LEA vs C)
¡ mismo tipo !¡ mismo tipo !
returnreturn asigna un valor a la función
returnreturn asigna un valor a la función
Curso 04-05. Práctica 3 6
Funciones
LEAfunc factorial (n: entero) dev (f: entero)Pre: {n>=0}Post: {f=n!}var i: enteroprin <f, i> := <1, 0> mientras i < n i := i + 1 f := f * i fmientrasfin
LEAfunc factorial (n: entero) dev (f: entero)Pre: {n>=0}Post: {f=n!}var i: enteroprin <f, i> := <1, 0> mientras i < n i := i + 1 f := f * i fmientrasfin
Cint factorial (int n){ int f = 1, i = 0;
while (i < n) { i++; f = f * i; } return f;}
Cint factorial (int n){ int f = 1, i = 0;
while (i < n) { i++; f = f * i; } return f;}
Definición de Función: (ejemplo)
El valor que tenga variable f cuando se ejecute la sentencia return será el valor que tome la función factorial
El valor que tenga variable f cuando se ejecute la sentencia return será el valor que tome la función factorial
Curso 04-05. Práctica 3 7
Funciones
LEAEn una asignación: variable := nombre_función (lista de parámetros)Dentro de una expresión: E (x, nombre_función (lista de parámetros))
LEAEn una asignación: variable := nombre_función (lista de parámetros)Dentro de una expresión: E (x, nombre_función (lista de parámetros))
CEn una asignación: variable = nombre_función (lista de parámetros);Dentro de una expresión: E (x, nombre_función (lista de parámetros))
CEn una asignación: variable = nombre_función (lista de parámetros);Dentro de una expresión: E (x, nombre_función (lista de parámetros))
Llamada a una Función: (LEA vs C)
Dado que después de la ejecución de una función esta toma un valor, puede ser usada como una variable que almacena dicho valor y, por ejemplo, asignarla a una variable.
Dado que después de la ejecución de una función esta toma un valor, puede ser usada como una variable que almacena dicho valor y, por ejemplo, asignarla a una variable.
Curso 04-05. Práctica 3 8
Funciones
LEAa, b, f, año, ndias: entero
En una asignación:f := factorial (5)f := factorial (a) / factorial (a-b)
Dentro de una expresión:si esBisiesto(año) ndias := 366fsi
LEAa, b, f, año, ndias: entero
En una asignación:f := factorial (5)f := factorial (a) / factorial (a-b)
Dentro de una expresión:si esBisiesto(año) ndias := 366fsi
Cint a, b, f, anyo, ndias;
En una asignación:f = factorial (5);f = factorial (a) / factorial (a-b);
Dentro de una expresión:if (esBisiesto(anyo)) ndias = 366;
Cint a, b, f, anyo, ndias;
En una asignación:f = factorial (5);f = factorial (a) / factorial (a-b);
Dentro de una expresión:if (esBisiesto(anyo)) ndias = 366;
Llamada a una Función: (ejemplo)
Curso 04-05. Práctica 3 9
C#include <stdio.h>int factorial (int);void main (void){ int fac; fac = factorial (7);
C#include <stdio.h>int factorial (int);void main (void){ int fac; fac = factorial (7);
Funciones
Una función (en ejemplo: factorial), puede retornar en cada llamada un único valor a otra función que la invoca (en ejemplo: main). La palabra reservada return permite asignar este valor a la función invocada (en ejemplo: factorial ( )).
Cint factorial (int n){ int f = 1, i = 0; while (i < n) { i++; f = f * i; } return f;}
Cint factorial (int n){ int f = 1, i = 0; while (i < n) { i++; f = f * i; } return f;}
7
5040
C#include <stdio.h>int factorial (int);void main (void){ int fac; fac = factorial (7); printf (“Factorial de 7 = %d”, fac);}
C#include <stdio.h>int factorial (int);void main (void){ int fac; fac = factorial (7); printf (“Factorial de 7 = %d”, fac);}
5040 5040
Curso 04-05. Práctica 3 10
Funciones
Se utiliza como argumentos de salida o de entrada/salida.
Permite el comportamiento de una función como procedimiento.
Es necesario el uso de punteros.
PASO DEPARÁMETROS
POR VALORPOR
REFERENCIA
Se utilizan como argumentos de entrada
Curso 04-05. Práctica 3 11
Funciones
Paso de parámetros por valor:Los valores de las variables o de las constantes que se escriben como argumentos en la invocación de una función, se copian en las direcciones de memoria reservada a los parámetros formales de la función invocada.
0x
0y
0z
0.0media
3
6
7
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0;
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0;
Memoria main #include <stdio.h>
float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0;
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0;
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z);
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z);
73 6
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z); media = media_aritmetica (x, y, z);
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x=0, y=0, z=0; float media=0.0; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z); media = media_aritmetica (x, y, z);
Memoria media_aritmética
float media_aritmética (int a, int b, int c)
{
float media_aritmética (int a, int b, int c)
{3a
7b
6c
float media_aritmética (int a, int b, int c)
{ a = a + b + c;
float media_aritmética (int a, int b, int c)
{ a = a + b + c;
16 float media_aritmética (int a, int b, int c)
{ a = a + b + c; return (a / 3.0);
float media_aritmética (int a, int b, int c)
{ a = a + b + c; return (a / 3.0);
float media_aritmética (int a, int b, int c)
{ a = a + b + c; return (a / 3.0);}
float media_aritmética (int a, int b, int c)
{ a = a + b + c; return (a / 3.0);}
5.333 ...
5.33
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x, y, z; float media; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z); media = media_aritmetica (x, y, z); printf (“La media vale %f\n”,media);}
#include <stdio.h>float media_aritmética (int, int, int);void main (void){ int x, y, z; float media; printf (“\n Teclee tres números:”); scanf (“%d%d%d”, &x, &y,&z); media = media_aritmetica (x, y, z); printf (“La media vale %f\n”,media);}
5.33...
5,33
Curso 04-05. Práctica 3 12
Funciones
En C no existen procedimientos, pero se puede conseguir que una función actúe como un procedimiento mediante el uso de punteros en los parámetros formales de la función.
Un puntero es una variable capaz de almacenar direcciones de memoria y mediante los operadores adecuados acceder a la información que contiene la dirección de memoria a la que “apunta” en cada momento.•Operador * sirve para:– Declarar un puntero, (p.e.: int *pint, float *pf;)– Acceder la información apuntada por el puntero.
•Operador & devuelve la dirección donde el compilador ubica una variable en la memoria.
Paso de parámetros por referencia I:
Curso 04-05. Práctica 3 13
5x
8y
8A48
8A4A
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8;
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8;
Memoriamain
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y);
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y);
Funciones
Paso de parámetros por referencia II:
void intercambio (int *p1, int *p2){
void intercambio (int *p1, int *p2){
8A48p1
8A4Ap2
Memoriaintercambio
Se pasan las direcciones de las variables que queremos sean modificadas por la función, de manera que dentro de la función definimos los correspondientes punteros que almacenan las citadas direcciones.
Se pasan las direcciones
Son punteros almacenan direcciones
?tmp
void intercambio (int *p1, int *p2){ int tmp;
void intercambio (int *p1, int *p2){ int tmp;
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1;
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1;
8
5
El contenido de lo apuntado por p15
5
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2;
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2;
8 void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp;
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp;
5
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp;}
void intercambio (int *p1, int *p2){ int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp;}
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y); printf (“\n x= %d”, x); printf (“\n y= %d”, y);
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y); printf (“\n x= %d”, x); printf (“\n y= %d”, y);
8
5
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y); printf (“\n x= %d”, x); printf (“\n y= %d”, y);}
#include <stdio.h>void intercambio (int *, int *);void main (void){ int x=5, y=8; intercambio (&x, &y); printf (“\n x= %d”, x); printf (“\n y= %d”, y);}
8
5
Curso 04-05. Práctica 3 14
Funciones
Ejemplos de uso de operadores de punteros.-
Se declaran dos variable enteras “i” y “j” y un puntero a entero “p”int i, j, *p;
Suponemos que “i” y “j” se ubican en las direcciones 13B6 e 5FC4, respectivamente. Contenido
de la memoria
13B6
?
5FC4
?
?
?
i
j
p
Variableoperación
i=15; 15p=&i; (p “apunta” a i)
j=*p; (se accede a lo apuntado por p) 13B6
15
Curso 04-05. Práctica 3 15
Funciones
LEAproc nombre (ent e1:Te1; ...; en:Ten;
sal s1:Ts1; ...; sm:Tsm; es r1:Tr1; ...; rp:Trp)
Pre: {P(e1, ..., en, r1, ..., rp)}Post: {Q(e1, ..., en, s1, ..., sm, r1, ..., rp)}cons definición de constantesvar declaración de variablesprin sentencias exp (ei, si, ri, x) sentenciasfin
LEAproc nombre (ent e1:Te1; ...; en:Ten;
sal s1:Ts1; ...; sm:Tsm; es r1:Tr1; ...; rp:Trp)
Pre: {P(e1, ..., en, r1, ..., rp)}Post: {Q(e1, ..., en, s1, ..., sm, r1, ..., rp)}cons definición de constantesvar declaración de variablesprin sentencias exp (ei, si, ri, x) sentenciasfin
Ctypedef Ts1 * PTs1;...typedef Tr1 * PTr1;...void nombre (Te1 e1, ..., Ten en, PTs1 s1, ..., PTsm sm, PTr1 r1, ..., PTrp rp){ declaración de variables
instrucciones exp (ei, *si, *ri, x); instrucciones}
Ctypedef Ts1 * PTs1;...typedef Tr1 * PTr1;...void nombre (Te1 e1, ..., Ten en, PTs1 s1, ..., PTsm sm, PTr1 r1, ..., PTrp rp){ declaración de variables
instrucciones exp (ei, *si, *ri, x); instrucciones}
Definición de Procedimiento: (LEA vs C)
Curso 04-05. Práctica 3 16
Funciones
#include <stdio.h>typedef int * Pint;typedef float * Pfloat;void MulDiv (int, int, Pint, Pfloat);void main (void){ int x, y, m; float d; printf (“\n Teclee dos números:”); scanf (“%d%d”, &x, &y); MulDiv (x, y, &m, &d); printf (“%d * %d=%d”, x, y, m); printf (“%d / %d =%f”, x, y, d);}
#include <stdio.h>typedef int * Pint;typedef float * Pfloat;void MulDiv (int, int, Pint, Pfloat);void main (void){ int x, y, m; float d; printf (“\n Teclee dos números:”); scanf (“%d%d”, &x, &y); MulDiv (x, y, &m, &d); printf (“%d * %d=%d”, x, y, m); printf (“%d / %d =%f”, x, y, d);}
Ejemplo de llamada y Definición de Procedimiento:
Distinguir entre el operador “*” de multiplicación, y el operador “*” de contenido
Llamadas por valor : “x” e “y”Llamadas por referencia: “m” y “d”
void MulDiv (int op1, int op2, Pint mul, Pfloat div){ assert (op2!=0) ; * mul = op1 * op2; * div = (1.0* op1) / op2;}
void MulDiv (int op1, int op2, Pint mul, Pfloat div){ assert (op2!=0) ; * mul = op1 * op2; * div = (1.0* op1) / op2;}
printf (“\n Teclee dos números:”);