logo sinuh
 

Inicio arrow Conocimiento arrow Curso de programación en C desde cero arrow Entrega 13. Funciones (II).
Entrega 13. Funciones (II). Imprimir
Por Luis García Galván   
sábado, 03 mar 2007 10:51

CURSO DESDE 0 DE PROGRAMACIÓN C BAJO GNU/LINUX.


Entrega 13. Funciones (II).

 

Tipo de resultado.


Como vimos en la entrega anterior, el tipo de resultado se define antes del nombre de la función y representa el tipo de valor que devolverá la función.


    int te_doy_un_numero()

      {
       ...
      }


Si no le indicamos ningún tipo de resultado, se da por supuesto que el valor de retorno es un 'int' y precisamente es por esto que estamos hartos de ver este aviso: “warning: return type of 'main' is not 'int'”, y por fin vamos a ver cómo quitar este aviso que he dejado a propósito entrega tras entrega, así que lo anterior equivale a:


    te_doy_un_numero()
      {
        ...
      }


¿Y qué ocurre en el caso de simular un procedimiento? O lo que es lo mismo, una función que no retorna valor. En ese caso le indicamos un tipo de retorno 'void'.


    void no_te_doy_ni_las_gracias()

      {
        ...
      }


La verdad, la mejor opción es poner siempre un valor de retorno y eliminar todo tipo de avisos (los “warnings”).


En el nombre del nombre de la función.


Sólo hay que resaltar que el nombre de la función está sujeto a las mismas normas que los nombres de los identificadores ya vistos.


Los parámetros.


Y aquí es donde vemos la diferencia entre las dos formas de definir las funciones, y aunque hagamos un ejemplo de ambas más adelante, sólo voy a explicar la forma de ANSI C y usarla de aquí en adelante.


    int potencia (int base , int exponente)

      {
      ...
      }


Los parámetros son valores que van a usarse dentro de una función. En el momento de la llamada a la función se realiza una copia de los valores (copia de parámetros reales a formales), y así los cambios realizados dentro de la función no afectan a las variables con los que se pasaron los parámetros a dicha función. ¿A que te has liado? Pues yo supongo que también, así que habrá que esperar a volver a leerlo con el ejemplo.


Existe otro modo de pasar las variables y se llama 'por referencia', pero no lo veremos hasta que lleguemos a los punteros.


Devolver un valor en una función.


Para devolver un valor en una función necesitamos una instrucción:


return expresión;


'return' finaliza la función devolviendo el control a la función llamadora junto con el valor de la expresión que es del tipo de resultado declarado en la función.


Debemos tener en cuenta que 'return' no es una función sino una palabra reservada de C, por lo que no necesita paréntesis aunque 'return (expresión);' es totalmente válido. Si no se devuelve ningún valor (el caso de 'void'), no hay que usar return.


Y para terminar, nos queda el prototipo.


C nos da la posibilidad de declarar las funciones antes de su definición, y esto tiene dos propósitos muy importantes:


  1. Evitar conversiones erróneas de valores

  2. Evitar errores en número o tipo de argumentos.


Lo metemos todo en una coctelera y sale el ejemplo.


Este es el código:


#include <stdio.h>


//Definición K&R

int suma (a,b)
   int a;
   int b;
  {

       a=a+b;
       return a;
  }


void adios ()

  {
       printf ("adios\n");
  }


int main (void)

  {
       int x,y;
       long z;
       x=5;
       y=2;
       z=potencia(x,y);
       printf ("La suma de %d mas %d es igual a %d\n",x,y,suma(x,y));
       printf ("%d elevado a %d es igual a %d\n",x,y,z);
       adios();
       return 0;
  }


//Definición ANSI

long potencia (int a, int b)

  {
       int i;
       long aux= 1;
       for (i=1;i<=b;i++) aux *=a;
       return aux;
  }


Y este el resultado:


matados2k@imperio:~/curso programacion$ cc -o ejemplo_13_1 ejemplo_13_1.c

ejemplo_13_1.c:32: error: conflicting types for 'potencia'

ejemplo_13_1.c:23: error: previous implicit declaration of 'potencia' was here

matados2k@imperio:~/curso programacion$


Ohhh error, tenemos que introducir los prototipos, porque si no cualquier función que usemos que esté definida después de donde se le llama, dará error. Como es el caso de “potencia” que está definido por debajo de 'main', que es donde se llama a ésta. Y además vamos a dejar todo lo más correcto posible.


Además vemos un elemento nuevo, estos son los comentarios de una sola línea, todo lo que vaya después de '//' será ignorado por el compilador desde su aparición hasta el final de la línea. Los comentarios no afectan al tamaño de los ejecutables y ayudan mucho a la comprensión del código, sobre todo si lo vamos a leer tiempo después. Hay otra forma de comentar que la introduciremos en próximos ejemplos.


Lo arreglamos:


#include <stdio.h>


//Declaración de prototipos

int suma (int a,int b);
  int a;
  int b;


void adios (void);
long potencia (int a, int b);


//Funciones

int main (void)
  {
    int x,y;
    long z;
    x=5;
    y=2;
    z=potencia(x,y);
    printf ("La suma de %d mas %d es igual a %d\n",x,y,suma(x,y));
    printf ("%d elevado a %d es igual a %d\n",x,y,z);
    adios();
    return 0;
  }


//Definición K&R

int suma (a,b)
  int a;
  int b;
  {
    a=a+b;
    return a;
  }


void adios (void)
  {
    printf ("adios\n");
  }


//Definición ANSI

long potencia (int a, int b)
  {

         int i;
    long aux= 1;
    for (i=1;i<=b;i++) aux *=a;
    return aux;
  }


Y vemos el resultado correcto:


matados2k@imperio:~/curso programacion$ ./ejemplo_13_1

La suma de 5 mas 2 es igual a 7

5 elevado a 2 es igual a 25

adios

matados2k@imperio:~/curso programacion$


Aquí hay algo que comentar, y es la copia de parámetros reales a parámetros formales. Lo vemos mejor con la función de suma, suma recibe una copia de los valores de 'x' e 'y' en 'a' y 'b' ('a' y 'b' podían haberse llamado perfectamente 'x' e 'y' para uso interno de la función y aumentar más la confusión) por eso al guardar el resultado sobre 'a' dentro de la función 'suma' la variable 'x' no ha variado en 'main'. Hay una forma diferente de pasar parámetros que sí cambiaría el valor de 'x', pero como ya comentamos anteriormente lo veremos cuando toquemos el tema de punteros.


Despedida.


Aquí tenemos que parar, la próxima semana terminaremos de ver las funciones. No me faltéis.


Agradecimientos:

· Revisión del documento: Karuchi (Carolina García).



Página oficial y dominio de mi propiedad http://matados2k.es

Matados'2k Usuario y moderador de www.sinuh.org

Matados'2k Moderador de foro.noticias3d.com


matados2k (arroba) gmail (punto) com


Este documento está sometido a la licencia de creative commons en su variante “Reconocimiento-NoComercial-SinObraDerivada 2.1 España” . Es de agradecer que se comunique al autor el uso de este documento en otro medio y se debe incluir de forma obligatoria este recuadro y los agradecimientos.

 

Comentario[s]

Sólo los usuarios registrados pueden escribir comentarios.
Por favor valídate o regístrate.

Powered by AkoComment 2.0!




© 2002-2005 SINUH - Comunidad GNU/Linux de Extremadura
Este portal utiliza Mambo
DHTML / JavaScript Tree by TwinHelix Designs

Para contactar con nosotros envía un correo a
info
Licencia Creative Commons
Los contenidos de este portal, salvo indicación en contra, están sujetos a una licencia de Creative Commons.

Los logotipos y marcas que aparecen son propiedad de sus respectivos dueños.

Las opiniones y declaraciones de las personas reflejadas en los foros y comentarios son propiedad y responsabilidad de sus autores, no identificando la opinión de SINUH y excluyendo de cualquier responsabilidad a esta asociación.
Ahora 10 visitantes
Advertisement