Yair Bahena. Con tecnología de Blogger.

jueves, 20 de noviembre de 2014

parte 3.

Definición y prototipos de funciones

Los programas sencillos, como los ejemplo planteados hasta ahora, normalmente no requieren un nivel de estructuración elevado. Pero cuando estos crecen un poco necesitamos estructurarlos adecuadamente para mantenerlos legibles, facilitar su mantenimiento y reutilizar ciertas porciones de código. El mecanismo C que nos permite esto son las funciones. Con los compiladores, los fabricantes nos proporcionan un conjunto importante de funciones de librería. A veces, nos puede interesar construir nuestras propias librerías. Ya hemos utilizado funciones, pero veamos cómo debemos definirlas.
Los prototipos de funciones son una característica clave de la recomendación ANSI del C. Un prototipo es una declaración que toma la forma:

tipo nombre ( tipo_parámetro nombre_parámetro ... ); 
Aquí tenemos varios ejemplos:

int fact_i ( int v );
int mayor ( int a, int b );
int cero ( double a );
long raiz ( long valor );
void final_countdown ( void );
int main ( int argc, char **argv );
Observando el prototipo de una función podemos decir exactamente qué tipo de parámetros necesita y qué resultado devuelve. Si una función tiene como argumento void, quiere decir que no tiene argumentos, al igual que si el resultado es void, no devuelve ningún valor. En la vieja definición de Kernighan y Ritchie el tipo que devolvía una función se declaraba únicamente si era distinto de int. Los parámetros eran declarados en el cuerpo de la función, en lugar de utilizar la lista de parámetros. Por ejemplo:


mayor ( a, b )
int a; int b;
{
...

ESTRUCTURA DE UNA FUNCION


#include <stdio.h>

void holamundo(void) /*Esta es la declaracion y a la vez la definicion de la funcion*/
{
  printf("Hola Mundo\n"); /* Esto lo que imprimira nuestra funcion */
return; /* sale de la función */
}

int main(void) /* Función principal del programa */
{
holamundo(); /* llamada a la función holamundo */
return 0; /* sale del programa con código 0 (correcto) */
}

Parámetros por referencia a funciones


En C todos los parámetros se pasan por valor. Esto tiene en principio dos inconvenientes: 
  • No se pueden modificar variables pasadas como argumentos
  • Si se pasa como parámetro una estructura, se realiza un duplicado de ella, con lo que se pierde tiempo y memoria

Sin embargo, se puede pasar un puntero como argumento a una función. El puntero no se puede alterar, pero sí el valor al que apunta: 

void incrementa_variable (int* var)
{
   (*var)++;
}

main()
{
   int x = 1;
   incrementa_variable (&x); /* x pasa a valer 2 */
}

En el ejemplo anterior, había que poner paréntesis en (*var)++ porque el operador ++ tiene más precedencia que la referencia (el asterisco). Entonces *var++ sería como escribir *(var++), que no sería lo que queremos. 


Se dice que una función es recursiva cuando se define en función de si misma.
No todas la funciones pueden llamarse a si mismas, sino que deben estar diseñadas especialmente para que sean re cursivas, de otro modo podrían conducir a bucles infinitos, o a que el programa termine in adecuadamente.
Tampoco todos los lenguajes de programación permiten usar recursividad.
C++ permite la recursividad. Cada vez que se llama a una función, se crea un juego de variables locales, de este modo, si la función hace una llamada a si misma, se guardan sus variables y parámetros, usando la pila, y la nueva instancia de la función trabajará con su propia copia de las variables locales. Cuando esta segunda instancia de la función retorna, recupera las variables y los parámetros de la pila y continua la ejecución en el punto en que había sido llamada.
Por ejemplo:
Podríamos crear una función recursiva para calcular el factorial de un número entero.
El factorial se simboliza como n!, se lee como "n factorial", y la definición es:
n! = n * (n-1) * (n-2) * ... * 1
Hay algunas limitaciones:
  • No es posible calcular el factorial de números negativos, no está definido.
  • El factorial de cero es 1.
De modo que una función bien hecha para cálculo de factoriales debería incluir un control para esos casos:
/* Función recursiva para cálculo de factoriales */
int factorial(int n) {
   if(n < 0) return 0;
   else if(n > 1) return n*factorial(n-1); /* Recursividad */
   return 1; /* Condición de terminación, n == 1 */
}

No hay comentarios.:

Publicar un comentario