Bienvenido(a), Visitante. Favor de ingresar o registrarse.

Ingresar con nombre de usuario, contraseña y duración de la sesión

Foros del Club

Páginas: [1]   Ir Abajo
  Enviar tema  |  Imprimir  
Autor Tema: Funciones con número variable de argumentos  (Leído 2256 veces)
0 Usuarios y 1 Visitante están viendo este tema.
CID
Administrador
Legend
*****

Prestigio: 22
Desconectado Desconectado

Sexo: Masculino
Estudiante de: Arte de la informática
Título universitario: Programador
Profesión: Desarrollador
Mensajes: 1136



WWW
Lenguajes:
Varios
Bases de datos:
Varios
« en: 14/08/2006, 19:22:50 »

Quien haya usado C++ alguna vez se ha encontrado con funciones como printf y scanf.
Esas funciones son especiales porque permiten ingresar un número arbitrario de argumentos (1 o más), primero vamos a explicar como trabaja una de éstas funciones.

Código
int  printf ( const char * format [ , argument , ...] );

Lo que nos interesa son los argumentos variables ([ , argument , ...]), los cuales pueden ser 0 o más y de cualquier tipo que la función pueda interpretar.
Por lo que las siguiente invocaciones son validas:

Código
printf("Hola!");
printf("No se para que estoy", 2);
printf("Soy un entero: %d", 34);
printf("Soy una cadena: %s\nY yo un numero: %f", "No se porque me dicen \"cadena\"...", -23.55);

Como podemos ver siempre debe estar el primer argumento (const char * format), porque internamente dá el comienzo del array de punteros que permite controlar la lista de argumentos consecuentes.

Ahora veamos como crear nuestra función que tome un entero y n enteros más:

Código
#include <stdarg.h>
 
int sumar(int count, ...)
{
 va_list pa;
 int suma = 0;
 va_start (pa, count);
 while(count--)
   suma+= va_arg (pa, int);
 va_end (pa);
 return suma;
}

Nuestra función sumar, suma count números y los retorna. La variable count debe contener la cantidad de argumentos variables que le pasamos la función. Prueben que pasa no le pasamos argumentos variables y count es mayor que cero (Por ejemplo: sumar(34)Gi&ntilde;ar.

Aqui el motor de dicha mágia es la cabecera stdarg.h la cual mantiene un conjunto de macros que nos posibilitan crear funciones de éste tipo.
Lo segundo que vemos es el prototipo de la función (int sumar(int count, ...)), y sus puntos suspensivos. Ellos indican que a partir de esa posición (el segundo parámetro) el número de parámetros es variable, es decir, le podemos enviar cero o más valores (o variables).
Luego va_list es un puntero a una "lista" que contiene una referencia a los argumentos variables. Para saber donde comienzan a llegar éstos argumentos se le debe indicar cual es el último argumento fijo (va_start), en nuestro caso es count. Para ir obteniendo los valores de los argumentos variables utilizamos va_arg(*lista, tipodelargumento), el cual nos retorna el valor del argumento siguiente y lo interpreta al tipodeargumento indicado (ésto puede ser un problema en tiempo de ejecución, ya hablaremos de ello).
Y por último liberamos los recursos de nuestra lista con va_end.

Como habiamos dicho antes, necesitamos conocer la cantidad y el tipo de los argumentos que nos llegan, y básicamente hay dos maneras: con un contador (y asumiendo un tipo de dato predeterminado, como es nuestro caso (enteros)), o con una cadena de formato, que es como trabaja printf y scanf.
La cadena de formato nos indica la cantidad y el tipo de los argumentos variables enviados a la función, por ejemplo:

Código
"Soy una cadena: %s\nY yo un numero: %f"

Asume que llegan 2 argumentos: %s y %f
Y que esos argumentos son: cadena (%s) y real (%f) respectivamente.
De esa manera se puede crear un algoritmo que sepa identificar el tipo de argumento que llega y actue en consecuencia.

Ésto es solo un vistazo, muy básico, sobre funciones con número arbitrario de parámetros.

Saludos.

PD: Que pasaría si tenemos argumentos fijos con valores por defecto? si quieren lo discutimos.
En línea

jam
Wizard
****

Prestigio: 0
Desconectado Desconectado

Mensajes: 9


Usuario Devs


« Respuesta #1 en: 17/08/2006, 20:15:27 »

Me parece muy buena la explicación anterior, y para platicar de parámetros por defecto (yo uso "por omisión")...

En C++ es posible definir el valor que un argumento de función tomará cuando al ser invocada dicha función el parametro no fuera asignado, esto es:

double divide (int a, int b=2)
{
    return a/b;
}

al invocar la función podríamos tener 2 opciones:

divide (8, 4); //devuelve 2
divide (10); //devuelve 5

como vemos en el primer caso realizamos 8/4 y en el segundo 10/2, notando que en el segundo caso al solo colocar un valor al llamar a la función, esta asume que el valor del segundo argumento es "2". Los argumentos por omisión deben cumplir con las siguientes reglas:

Los argumentos por defecto deben definirse a la izquierda de la lista.
No debemos colocar argumentos por defecto alternados con argumentos comunes.
Debemos evitar ambigüedades, especialmente al realizar sobrecarga de funciones.

Espero extiendan esta explicación y les propongo hablemos del paradigma de la programación orientada a objetos, conceptos básicos, definiciones y ejemplos.

Hasta pronto!
En línea
Mico el microfono
Visitante
« Respuesta #2 en: 18/08/2006, 02:02:57 »

Cheesy muy buena explicacion Sonrisa podrias explicar algo sobre clases y herencia?
 Feliz
En línea
CID
Administrador
Legend
*****

Prestigio: 22
Desconectado Desconectado

Sexo: Masculino
Estudiante de: Arte de la informática
Título universitario: Programador
Profesión: Desarrollador
Mensajes: 1136



WWW
Lenguajes:
Varios
Bases de datos:
Varios
« Respuesta #3 en: 18/08/2006, 14:05:35 »

Si, pero lo hacemos en otro tema, les parece? dejamos éste para funciones.
En línea

Tavo
Technocrat
*********

Prestigio: 0
Desconectado Desconectado

Sexo: Masculino
Título universitario: Ninguno
Profesión: GameDeveloper(GD) y Desarrollador
Mensajes: 144




Lenguajes:
Visual Basic
Real Basic
Python
C/C++
Java
SQL
Bases de datos:
SQLite
MySQL
« Respuesta #4 en: 18/08/2006, 14:09:20 »

Ya lo cree haci no desvirtuamos: http://foros.clubdesarrolladores.com.ar/index.php/topic,597.0.html
En línea

Foros del Club
   

 En línea
Páginas: [1]   Ir Arriba
  Enviar tema  |  Imprimir  
 
Ir a: