16
Curso 04-05. Prácti ca 3 1 Funciones CONTENIDO Consideraciones sobre funciones Estructura de un programa en C Uso de funciones Paso de parámetros Punteros Ejemplo

Funciones

  • 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

Page 1: Funciones

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

Page 2: Funciones

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.

Page 3: Funciones

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.

Page 4: Funciones

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, ...);

Page 5: Funciones

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

Page 6: Funciones

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

Page 7: Funciones

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.

Page 8: Funciones

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)

Page 9: Funciones

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

Page 10: Funciones

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

Page 11: Funciones

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

Page 12: Funciones

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:

Page 13: Funciones

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

Page 14: Funciones

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

Page 15: Funciones

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)

Page 16: Funciones

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:”);