logo sinuh
 

Inicio arrow Conocimiento arrow Curso de programación en C desde cero arrow Entrega 14. Funciones (y III).
Entrega 14. Funciones (y III). 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 14. Funciones (y III).

 

La función main.


Ya sabemos que la función 'main' es muy importante y necesaria en todo programa en C, de hecho es por donde un programa empieza a ejecutarse. De hecho, hemos visto definir a main de muchas formas y en alguna de ellas se producían avisos.


La forma real de usar 'main' es la siguiente:


int main (int argc, char *argv[]);


Y esta es su forma completa y la que usaremos a partir de ahora. Cuando utilizamos un comando, por ejemplo 'cat', muchas veces añadimos parámetros como pueden ser opciones o nombres de fichero, es la forma típica de: NombrePrograma [Argumento 1, Argumento 2, ... , Argumento N] . Pues bien, es en 'main' donde vamos a recibir esos parámetros a través de esas variables.


El parámetro argc contiene el número de argumentos pasados en línea de comando, que mínimo siempre va a valer 1 ya que el nombre del programa cuenta y el el primer parámetro de la lista.


El parámeto argv es un array de cadenas con cada una de las cadenas. Aun no hemos visto los arrays, y aunque los voy a usar en el ejemplo lo entenderéis perfectamente cuando lleguemos al tema de arrays y punteros.


De hecho, argc y argv son un nombre puesto por convención, puedes usar el nombre que quieras para cada uno de ellos. Esto pasa con cualquier prototipado de funciones, al compilador le da igual si tú haces:


   int molo_mucho (int cuanto, float cuando);


Y luego la defines así:


  int molo_mucho (int perro, float gato)

  {

    ...

  }


Esto se debe a que lo que realmente importa es la signatura de la función. Según wikipedia, La signatura de un método o una función define su entrada y su salida. Incluye por lo menos el nombre de la función o método y el número de sus parámetros. En algunos lenguajes de programación, puede incluir el tipo que devuelve la función o el tipo de sus parámetros.


Esto último no es el caso de C. Por lo que si tú has prototipado 'int molo_mucho (int cuanto, float cuando);' la signatura para el compilador será 'int molo_mucho (int,float);' y la definición anterior cumple con esta signatura, por lo tanto es válida aunque cambies los nombres de los parámetros.


Pues lo mismo pasa con 'main', y esa es la razón de que puedas poner el nombre que te dé la real gana a sus dos parámetros. La signatura de 'main' sería:


int main (int, char *[]);


Aunque para los puristas sería: 'int main (int, char **)' Y esto de debe a que es lo mismo, debido a la dualidad entre arrays y punteros que también es algo que veremos más adelante. De momento sólo tendréis que saber que '[]' = '*' para la signatura de una función.


Veamos un ejemplo:


#include <stdio.h>

void imprime (char *cadena);

int main (int cantidad , char *calidad[])
  {
    int i;
    if (cantidad > 6)
      {
        imprime ("Muchos argumentos, mejor calidad que cantidad");
        return -1;
      }
    for (i=cantidad-1;i>0;i--) imprime (calidad[i]);
    return 0;
}


void imprime (char *texto)
  {
    printf ("%s \n", texto);
  }


De ejecución:


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

matados2k@imperio:~/curso programacion$ ./ejemplo_14_1 casa coche perro gato avion comida ñapa

Muchos argumentos, mejor calidad que cantidad

matados2k@imperio:~/curso programacion$ ./ejemplo_14_1 esto mola como matados2k

matados2k

como

mola

esto

matados2k@imperio:~/curso programacion$


Aquí hay varias cosas que explicar, para empezar olvidaos de cómo manejo los arrays y las cadenas (que son arrays) hasta que llegue su momento, podemos observar lo que os comento de la signatura y cómo devuelvo un valor 0 cuando la ejecución ha sido correcta y -1 cuando no lo ha sido. Esto es una convención, imaginaos que un programa va a recoger la salida del nuestro, con esto sabría el otro programa que el nuestro ha fallado o no se ha ejecutado correctamente, así que recuerda, si el programa va bien devuelve 0 o en un defecto un positivo, si no devuelve un número negativo, de hecho puedes devolver un negativo distinto para cada error.


Funciones de librería.


Hemos visto que para usar funciones de la librería estándar de C usamos '#include <nombre_libreria.h>', pues ahora estamos en las condiciones de crear nuestras propias librerías de funciones usando:


#include “nombre_libreria.h”


Y vamos a aplicarlo a nuestro código, para ver cómo se haría la estructura de una programación modular ya comentada anteriormente, para ello usaremos ficheros con extensión .h para los archivos de cabecera que sólo contendrán variables globales (cosa que veremos justo en la siguiente entrega) que necesiten otros módulos (otros archivos .c), entencias 'include' y prototipo de funciones. Y los archivos con extensión .c para el código.


Archivo ejemplo_14_2.c:

#include "print.h"

int main (int cantidad , char *calidad[])
  {
    int i;
    if (cantidad > 6)
      {
        imprime ("Muchos argumentos, mejor calidad que cantidad");
        return -1;
      }
    for (i=cantidad-1;i>0;i--) imprime (calidad[i]);
    return 0;
}



Archivo print.h:

#include <stdio.h>

void imprime (char *);



Archivo print.c:

#include "print.h"

void imprime (char *texto)
  {
    printf ("%s \n", texto);
  }


De ejecución:

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

matados2k@imperio:~/curso programacion$ ./ejemplo_14_2 casa coche perro gato avion comida ñapa

Muchos argumentos, mejor calidad que cantidad

matados2k@imperio:~/curso programacion$ ./ejemplo_14_2 esto mola como matados2k

matados2k

como

mola

esto

matados2k@imperio:~/curso programacion


Analicemos, ahora para compilar debo añadir todos los archivos .c que uso, nada más de momento, y demuestro cómo en el prototipo de función puedo poner directamente la signatura. Estructurar los programas de esta forma es muy beneficioso, no sólo por el orden de tener todas las funciones referentes a un tema agrupados y aumentar la legibilidad del código, sino porque además la programación estructurada ayuda a la reutilización de código. Podemos coger una librería de un programa para usarlo en otro con sólo añadir un simple 'include'.


En este ejemplo tan efímero no pueden apreciarse sus ventajas, pero cuando hagamos ejemplos medianos y grandes lo prepararemos de esta forma.


Funciones con número variable de parámetros.


C nos permite usar funciones en las que no sabemos cuál va a ser la cantidad de parámetros que vamos a usar, lo vemos constantemente con la función de librería 'printf' . Nosotros podemos crear funciones de este estilo con la siguiente definición:


tipo_devuelto nombre ([ Parámetros_fijos], ...)


En resumen, que basta con añadir '...' al final de la función. Pero para manejar estos parámetros variables necesitamos usar unas funciones de librería que incluiremos con:


#include <stdarg.h>


Los argumentos variables se van a almacenar en una variable de tipo 'va_list':


# include <stdarg.h>

int suma (int operandos, ...)
{
  va_list lista;
}


Y para manejar los argumentos vamos a usar 3 funciones:


va_start (lista_de_argumentos, nombre_ultimo_argumento_fijo);


Se debe usar antes de las otras dos funciones que vamos a usar, se le pasará la variable que contiene la lista de argumentos y el nombre del último argumento fijo que de definió en la función. Se encarga de inicializar el contenido de la lista de argumentos.


tipo va_arg ( lista_de_argumentos, tipo);


Devuelve cada uno de los argumentos en orden, uno por cada llamada. le tenemos que indicar cómo se va a interpretar el tipo de la variable.


void va_end (lista_de_argumentos);


Se realiza esta llamada para finalizar la lista de argumentos.


Un ejemplo de esquema puede ser el siguiente:


# include <stdarg.h>

  int suma (int operandos, ...)
    {
      int aux;
      va_list lista;
      va_start (lista, operandos);
      ...
      aux= va_arg ( lista, int);
      ...
      va_end (lista);
    }


Despedida.


Y hasta aquí puedo contar, ya que el ejercicio de la semana es hacer une ejemplo de función que sume con un número indeterminado de parámetros y lo muestre por pantalla, y para eso ya tenéis el esquema preparado. Y para ver si se repite el éxito de respuesta, “no tengo esperanza de que me lleguen respuestas al ejercicio”. Un saludo y hasta la semana que viene.


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 13 visitantes
Advertisement