Transcript Capitulo4

Funciones: conceptos básicos

 Un programa “C” está formado por un conjunto de objetos externos que pueden ser variables o funciones.

 Cualquier programa “C” tiene al menos una función llamada

main

que es la función principal.

 Las funciones de “C” son porciones de código ejecutable que devuelven un valor al ser invocadas.

Este valor puede depender de los argumentos que se especifiquen en la llamada.

FUNCIONES Pág. 1 de 42

Funciones: conceptos básicos

 El intercambio de información entre dos funciones, cuando una llama a la otra, puede realizarse mediante:  el resultado devuelto por la función llamada,  los parámetros de la función llamada,  variables externas accesibles por ambas funciones.

 En “C” todas las funciones son externas, ya que no se permite la definición de funciones en el interior de otras funciones.

FUNCIONES Pág. 2 de 42

Definición de funciones

 La sintaxis aconsejada (“estilo nuevo”, introducido por el estándar ANSI) para la definición de una función es: [

clase

] [

tipo

]

bloque nombre_función

(

tipo_1 ident_1

,

...

,

tipo_n ident_n

);

 La sintaxis original (“estilo antiguo”, del “C” de K&R) de la definición de una función es: [

clase

] [

tipo

]

tipo_1 ident_1 nombre_función

,

...

, (

ident1 tipo_n ident_n

; ,

...

,

bloque ident_n

);

FUNCIONES Pág. 3 de 42

Definición de funciones

 Caso particular de una función sin parámetros:  estilo nuevo (ANSI): [

clase

] [

tipo

]

bloque nombre_función

( void );

 estilo antiguo (K&R): [

clase

] [

tipo

]

nombre_función

( );

bloque

 Si en el estilo antiguo no se proporciona la declaración de uno de los parámetros se considera que es de tipo

int

FUNCIONES Pág. 4 de 42

Definición de funciones

tipo

indica el tipo del valor devuelto por la función; en caso de no indicarse, se considera que el valor devuelto es de tipo

int

.

 Una función puede devolver un tipo aritmético, un puntero, una estructura, una unión o

void

(ANSI), pero no puede devolver ni una función ni un array.

nombre_función

es el identificador que se utilizará para invocar la función definida.

FUNCIONES Pág. 5 de 42

Definición de funciones

 El cuerpo de la función (

bloque

) especifica el conjunto de sentencias que se ejecutan al invocar a la función, entre ellas, el conjunto de declaraciones y definiciones internas de esa función.

clase

especifica la clase de almacenamiento de la función, que puede ser

extern

o

static

, siendo

extern

en el caso de no especificarse nada.

FUNCIONES Pág. 6 de 42

Definición de funciones

 Si la función es de clase

extern

puede utilizarse en todos los ficheros que forman el programa. Debe existir una sola definición de cada función de clase

extern

entre todos los ficheros que constituyen el programa.

 Si la función es de clase

static

, sólo puede utilizarse en el fichero en que se encuentra su definición; puede existir una definición de una función distinta con el mismo nombre en otro fichero del programa.

FUNCIONES Pág. 7 de 42

Definición de funciones

Se utiliza el término: 

parámetro formal

para referirse a las variables declaradas como argumentos de la función en su definición (las designadas por los identificadores

ident_1

,... ,

ident_n

).

parámetro actual

para referirse a las expresiones proporcionadas como argumentos en una llamada a la función, cuyos valores se asignarán a los correspondientes parámetros formales en el momento de ejecutarse la llamada.

FUNCIONES Pág. 8 de 42

Definición de funciones

 Los parámetros formales definen la interfaz de entrada de la función,  se consideran variables automáticas con alcance limitado al cuerpo de la función (

bloque

)  su nombre puede coincidir con otro identificador externo a la función.

 Los parámetros actuales definen la información que se quiere transferir a la función en el momento de invocarla.

FUNCIONES Pág. 9 de 42

Declaración de funciones

 La definición de una función sirve como declaración para el resto del fichero en que se encuentra.

 Cuando es necesario hacer referencia a una función antes de su definición, o desde otro fichero distinto al de su definición, se debe realizar una declaración anticipada.

 La declaración anticipada especifica al compilador al menos el tipo y nombre de la función, para que pueda ser invocada fuera del alcance de su definición.

FUNCIONES Pág. 10 de 42

Declaración de funciones

 La sintaxis aconsejada (“estilo nuevo”, introducida por el estándar ANSI) para la declaración de una función es: [

clase

] [

tipo

]

nombre_función

(

tipo_1 ident_1

,

...

,

tipo_n ident_n

);

 La sintaxis original (“estilo antiguo”, del “C” de K&R) de la declaración de una función es: [

clase

] [

tipo

]

nombre_función

( );

 La clase de almacenamiento puede ser

extern

o

static

 si se omite el tipo se considera

int

 si se omite la clase se considera

extern

FUNCIONES Pág. 11 de 42

Declaración de funciones: estilo antiguo

 Si la llamada de una función ocurre dentro del alcance de una declaración de estilo antiguo el resultado es indefinido:  si el número de parámetros actuales no se corresponde con el número de parámetros formales  si los tipos de los parámetros actuales no concuerdan con los de los correspondientes parámetros formales, después de llevar a cabo las promociones de tipo adecuadas.

FUNCIONES Pág. 12 de 42

Declaración de funciones: declaración implícita

 La primera llamada a una función, ninguna

f

, cuando no existe declaración dentro de cuyo ámbito se encuentre, lleva implícita su declaración como:

extern int f( );

en el bloque más interior que contiene la llamada.

 Si en el mismo programa se ha definido una función del mismo nombre que devuelve un tipo distinto de int, el resultado es indefinido.

 Se considera mala práctica hacer uso de este tipo de declaración implícita.

FUNCIONES Pág. 13 de 42

Prototipos de funciones

 El concepto más amplio de declaración de función del estándar ANSI, que incluye la especificación del número y los tipos de los parámetros (el estilo nuevo), se denomina

prototipo de función

.

 Habitualmente, los prototipos de función se sitúan, o bien al principio de cada fichero en que aparece una llamada a la correspondiente función, o bien en un fichero de encabezado que se incluye en cada uno de estos ficheros.

FUNCIONES Pág. 14 de 42

Prototipos de funciones

 Los prototipos de función permiten:  la comprobación, en tiempo de compilación, de la correspondencia entre el número de los parámetros actuales y formales (excepción: las funciones variádicas).

 la conversión automática, en tiempo de ejecución, de los tipos de los parámetros actuales en los tipos de los parámetros formales (como si se tratara de asignaciones)

FUNCIONES Pág. 15 de 42

Prototipos de funciones

 ANSI introdujo un nuevo tipo de datos básico,

void

, para indicar que una función no devuelve ningún valor, o que la función no tiene parámetros.

 Ejemplo:

void hola(void); void hola(void) { /* /*

prototipo definición

printf(“Hola\n”); } */ */

FUNCIONES Pág. 16 de 42

Parámetros de una función

 Todos los parámetros se pasan por valor, es decir, si se pasa una variable a una función como parámetro actual, se genera una copia de esta variable y la función trabaja sobre esta copia.

 La función sólo puede modificar el valor de la copia de la variable que se le pasa como parámetro actual, no puede modificar el valor de la variable en sí.

FUNCIONES Pág. 17 de 42

Parámetros de una función

 Una función puede modificar el valor de una variable

dirección

se le pasa como parámetro actual.

cuya

 De esta manera, se simula la posibilidad de pasar parámetros por referencia que existe en otros lenguajes (atención al uso del operador unario

&

).

FUNCIONES Pág. 18 de 42

Reglas de ámbito

 Las reglas de ámbito de un lenguaje son aquellas que gobiernan si un segmento de código conoce la existencia de, o tiene acceso a, otro segmento de código.

 El ámbito de los identificadores declarados como parámetros formales es la propia función.

 El bloque de código más común en cuyo interior se declaran variables es el cuerpo de una función.

FUNCIONES Pág. 19 de 42

Reglas de ámbito

 El ámbito de una declaración externa abarca desde el punto en el que se realiza su declaración en un fichero hasta el final de ese fichero.

 El ámbito de una declaración interna a un bloque comprende desde el lugar de la declaración hasta el final de ese bloque.

FUNCIONES Pág. 20 de 42

Reglas de ámbito: variables

 Las variables externas se definen una sola vez fuera de todas las funciones y, si esta definición no precede a la definición de la función que la utiliza, la función tiene que incluir una declaración externa (con la palabra clave

extern

) de esta variable.

 Si una variable local y una variable global tienen el mismo nombre, todas las referencias a ese nombre dentro del ámbito de la variable local se refieren a la variable local.

FUNCIONES Pág. 21 de 42

Reglas de ámbito: variables

Variables estáticas externas

: sólo pueden ser referenciadas en el resto del fichero en el que se definen (no desde el resto de ficheros que forman el programa).

Variables estáticas internas

: sólo pueden ser referenciadas en el interior del bloque en el que se definen, pero conservan su valor entre ejecuciones sucesivas del bloque.

FUNCIONES Pág. 22 de 42

Recursión

 Cuando durante la ejecución de una función se realiza una invocación de esa misma función, se dice que se produce una llamada recursiva.

 La recursión puede ser de dos tipos: 

recursión propia

: la explícitamente a sí misma.

función se invoca 

recursión mutua

: la función llama a otra función que directa o indirectamente la invoca.

FUNCIONES Pág. 23 de 42

Recursión

 Las soluciones no recursivas son en general más eficientes, en términos de espacio de almacenamiento y tiempo de ejecución, que las recursivas.

 Cada vez que se invoca a una función se crea un nuevo juego de variables automáticas, y se las inicializa con el valor de los correspondientes parámetros formales.

FUNCIONES Pág. 24 de 42

Recursión

 Hay muchos casos en que el modo más natural de describir un proceso es mediante una formulación recursiva (p.e. manipulación de árboles).

 Una función recursiva tiene que contener una sentencia condicional en una de cuyas ramas termina la recursión (no contiene una llamada recursiva).

FUNCIONES Pág. 25 de 42

Preprocesador de C

 En el código fuente se puede incluir una serie de instrucciones especiales que no pertenecen al lenguaje en sí y que facilitan el desarrollo de los programas.

 Las instrucciones se denominan

directivas

, y se procesan al principio de la compilación del programa con el

preprocesador

.

fich.c

Preprocesador fich.i

Compilador fich.o

FUNCIONES Pág. 26 de 42

Preprocesador de C

 Las directivas del preprocesador pueden aparecer en cualquier parte del programa, pero sólo tendrán efecto en la porción del programa que sigue a su aparición.

 Toda aquella línea que comience con

#

es una directiva del preprocesador; la sintaxis de estas directivas es independiente del resto del lenguaje.

 Por convenio se utilizan letras mayúsculas para los nombres definidos en las directivas, p.e.

# define TAM-MAX 100

FUNCIONES Pág. 27 de 42

Preprocesador de C

Sustitución de Macros

# define

ident tokens

# define

ident

(

lista_id

)

tokens

# undef

ident

Inclusión de Ficheros

# include <

nom_fichero

> # include “

nom_fichero

Compilación Condicional

# if

expresión_const

# else # elif

expresión_const

*

# endif # ifdef

ident

# ifndef

ident

otras utilidades * = sólo ANSI

# line

constante

# pragma

tokens

*

# error

tokens

*

# defined

ident

*

FUNCIONES Pág. 28 de 42

Preprocesador de C macros

 Una macro define un texto que ha de insertarse en el fichero fuente de un programa durante su compilación.

 El texto que se ha de insertar puede depender de los parámetros de la macro.

FUNCIONES Pág. 29 de 42

Preprocesador de C macros sin parámetros

# define

: se utiliza para definir un identificador junto con una secuencia de caracteres que se pondrán en lugar del identificador cada vez que este aparezca en el fichero fuente. Su sintaxis es:

# define

nombre_macro cadena

 No forman parte de

cadena

los blancos localizados entre

nombre_macro

y el primer token y entre el último token y el salto de línea.

FUNCIONES Pág. 30 de 42

Preprocesador de C macros sin parámetros

 Si la cadena no cabe en una sola línea se continúa en la siguiente, después de escribirse la barra invertida

\

.

 Provoca que el procesador sustituya las apariciones de

nombre_macro

por la cadena de caracteres que le siguen.

 La sustitución no se lleva a cabo dentro de constantes carácter o cadena de caracteres.

FUNCIONES Pág. 31 de 42

Preprocesador de C macros con parámetros

 La sintaxis de una macro que tiene argumentos es:

# define

nombre_macro

(

id1

,

,

idn

)

cadena

 Las siguientes apariciones (“llamadas” a la macro) de

nombre_macro

(

lista_de_cadenas_de_caracteres

)

se sustituyen por la cadena

cadena

.

 Cada parámetro formal especificado en la definición se sustituye en

cadena

por el correspondiente parámetro actual de la “llamada” a la macro.

FUNCIONES Pág. 32 de 42

Preprocesador de C macros con parámetros

 No puede haber ningún

nombre_macro

y el paréntesis.

espacio entre  Los números de parámetros actuales y formales deben coincidir.

 Los parámetros actuales se separan en la llamada a la macro mediante comas.

  Una macro no se puede pasar a una función como parámetro.

Una macro no recursivamente.

puede llamarse a sí misma

FUNCIONES Pág. 33 de 42

Preprocesador de C macros con parámetros, advertencias

 Se debe encerrar entre paréntesis cada aparición de los parámetros en la definición de la macro.

 Se debe encerrar toda la definición de la macro entre paréntesis.

 Hay que tener cuidado con el número de veces que se evalúan los parámetros formales.

FUNCIONES Pág. 34 de 42

Preprocesador de C macros o funciones

 Ventajas (de macros)  son más rápidas que las llamadas a funciones.

 dado que sólo realizan sustituciones de texto, la misma macro puede servir para cualquier tipo de datos.

 se puede pasar el nombre de un tipo como parámetro  Desventajas (de macros)  ocupan más espacio que las funciones, ya que una macro se puede insertar varias veces en el código  su sintaxis es más delicada que la de las funciones.

FUNCIONES Pág. 35 de 42

Preprocesador de C eliminación de definiciones

 Se puede hacer que una macro deje de estar definida en el preprocesador como sigue:

# undef

nombre_macro FUNCIONES Pág. 36 de 42

Preprocesador de C inclusión de ficheros

 Esta directiva provoca que el compilador pase a compilar el fichero cuyo nombre se especifica y cuando finalice continúe con la siguiente línea del fichero actual. Su sintaxis es:

# include “

nombre_fichero

” # include <

nombre_fichero

>

 Se admite que los ficheros incluidos tengan, a su vez, directivas

# include

.

 Esta directiva permite que varios ficheros fuente que forman parte del mismo programa compartan las mismas declaraciones

FUNCIONES Pág. 37 de 42

Preprocesador de C compilación condicional

 Estas directivas permiten compilar selectivamente partes del código fuente del programa.

 Si la expresión constante es cierta (se evalúa a un valor distinto de cero) se compila la lista de sentencias, en caso contrario, no se compila.

# if

expresión_constante lista-sentencias

# endif

FUNCIONES Pág. 38 de 42

Preprocesador de C compilación condicional

 Si la expresión constante es cierta (distinta de cero) se compila la primera lista de sentencias, si es falsa, se compila la segunda lista de sentencias.

# if

expresión_constante lista_sentencias_1

# else

lista_sentencias_2

# endif

FUNCIONES Pág. 39 de 42

Preprocesador de C compilación condicional

 Se evalúan las expresiones constantes en el orden en que aparecen. Cuando una expresión sea cierta, se compilan las sentencias correspondientes y se sigue compilando la siguiente línea tras

#endif

.

# if

expresión_constante1

# elif

lista_sentencias_1 expresión_constante2

...

# else

lista_sentencias_2

# endif

lista_sentencias FUNCIONES Pág. 40 de 42

Preprocesador de C compilación condicional

 Otra directiva de compilación condicional es

ifdef

 Si el nombre de la macro está definido previamente para el procesador (mediante

#define

), se compilan las sentencias, si no está definido no se compilan.

# ifdef

identificador lista_sentencias

# endif

 Puede utilizarse en combinación con la directiva

#else

FUNCIONES Pág. 41 de 42

Preprocesador de C compilación condicional

 La directiva “inversa” a

ifdef

es

ifndef

 Si el nombre de la macro no está definido previamente para el procesador, se compilan las sentencias, si está definido no se compilan.

# ifndef

identificador lista_sentencias

# endif

 Puede utilizarse en combinación con la directiva

#else

FUNCIONES Pág. 42 de 42