En aquest tema, explorarem com gestionar funcions que poden rebre un nombre variable d'arguments. Aquestes funcions són molt útils quan no sabem per endavant quants arguments es passaran a la funció. Un exemple clàssic d'aquesta funcionalitat és la funció printf
de la biblioteca estàndard de C.
Conceptes Clau
- Llistes d'Arguments Variables: Permeten que una funció accepti un nombre indeterminat d'arguments.
- Biblioteca
stdarg.h
: Proporciona macros per gestionar arguments variables. - Macros Principals:
va_list
: Tipus de dades per emmagatzemar la llista d'arguments.va_start
: Inicialitza la llista d'arguments.va_arg
: Recupera un argument de la llista.va_end
: Finalitza l'ús de la llista d'arguments.
Exemples Pràctics
Exemple 1: Funció que Suma Nombres
A continuació, es mostra una funció que suma un nombre variable d'arguments:
#include <stdio.h> #include <stdarg.h> int suma(int num_args, ...) { va_list args; va_start(args, num_args); int sum = 0; for (int i = 0; i < num_args; i++) { sum += va_arg(args, int); } va_end(args); return sum; } int main() { printf("Suma de 1, 2, 3: %d\n", suma(3, 1, 2, 3)); printf("Suma de 4, 5, 6, 7: %d\n", suma(4, 4, 5, 6, 7)); return 0; }
Explicació del Codi
- Declaració de la Funció:
int suma(int num_args, ...)
indica que la funció accepta un nombre variable d'arguments després del primer argumentnum_args
. - Inicialització de la Llista d'Arguments:
va_list args; va_start(args, num_args);
inicialitza la llista d'arguments. - Recuperació d'Arguments:
sum += va_arg(args, int);
recupera cada argument de la llista. - Finalització de la Llista d'Arguments:
va_end(args);
finalitza l'ús de la llista d'arguments.
Exemple 2: Funció que Troba el Màxim
A continuació, es mostra una funció que troba el màxim d'un nombre variable d'arguments:
#include <stdio.h> #include <stdarg.h> int max(int num_args, ...) { va_list args; va_start(args, num_args); int max_val = va_arg(args, int); for (int i = 1; i < num_args; i++) { int val = va_arg(args, int); if (val > max_val) { max_val = val; } } va_end(args); return max_val; } int main() { printf("Màxim de 1, 2, 3: %d\n", max(3, 1, 2, 3)); printf("Màxim de 4, 5, 6, 7: %d\n", max(4, 4, 5, 6, 7)); return 0; }
Explicació del Codi
- Inicialització de la Llista d'Arguments:
va_list args; va_start(args, num_args);
inicialitza la llista d'arguments. - Recuperació del Primer Argument:
int max_val = va_arg(args, int);
recupera el primer argument. - Comparació d'Arguments:
if (val > max_val) { max_val = val; }
compara cada argument amb el màxim actual. - Finalització de la Llista d'Arguments:
va_end(args);
finalitza l'ús de la llista d'arguments.
Exercicis Pràctics
Exercici 1: Funció que Calcula la Mitjana
Escriu una funció que calculi la mitjana d'un nombre variable d'arguments.
#include <stdio.h> #include <stdarg.h> double mitjana(int num_args, ...) { // Implementa la funció aquí } int main() { printf("Mitjana de 1, 2, 3: %.2f\n", mitjana(3, 1, 2, 3)); printf("Mitjana de 4, 5, 6, 7: %.2f\n", mitjana(4, 4, 5, 6, 7)); return 0; }
Solució
#include <stdio.h> #include <stdarg.h> double mitjana(int num_args, ...) { va_list args; va_start(args, num_args); double sum = 0; for (int i = 0; i < num_args; i++) { sum += va_arg(args, int); } va_end(args); return sum / num_args; } int main() { printf("Mitjana de 1, 2, 3: %.2f\n", mitjana(3, 1, 2, 3)); printf("Mitjana de 4, 5, 6, 7: %.2f\n", mitjana(4, 4, 5, 6, 7)); return 0; }
Exercici 2: Funció que Troba el Mínim
Escriu una funció que trobi el mínim d'un nombre variable d'arguments.
#include <stdio.h> #include <stdarg.h> int min(int num_args, ...) { // Implementa la funció aquí } int main() { printf("Mínim de 1, 2, 3: %d\n", min(3, 1, 2, 3)); printf("Mínim de 4, 5, 6, 7: %d\n", min(4, 4, 5, 6, 7)); return 0; }
Solució
#include <stdio.h> #include <stdarg.h> int min(int num_args, ...) { va_list args; va_start(args, num_args); int min_val = va_arg(args, int); for (int i = 1; i < num_args; i++) { int val = va_arg(args, int); if (val < min_val) { min_val = val; } } va_end(args); return min_val; } int main() { printf("Mínim de 1, 2, 3: %d\n", min(3, 1, 2, 3)); printf("Mínim de 4, 5, 6, 7: %d\n", min(4, 4, 5, 6, 7)); return 0; }
Errors Comuns i Consells
- No oblidar
va_end
: Sempre assegura't de cridarva_end
per evitar fuites de memòria. - Tipus d'Arguments: Assegura't que els tipus d'arguments passats a
va_arg
coincideixin amb els tipus reals dels arguments. - Nombre d'Arguments: Assegura't que el nombre d'arguments passat a la funció coincideixi amb el nombre real d'arguments.
Resum
En aquest tema, hem après com gestionar funcions amb un nombre variable d'arguments utilitzant la biblioteca stdarg.h
. Hem vist exemples pràctics i hem practicat amb exercicis per reforçar els conceptes apresos. Ara estàs preparat per utilitzar llistes d'arguments variables en les teves pròpies funcions en C.
Curs de Programació en C
Mòdul 1: Introducció al C
- Introducció a la Programació
- Configuració de l'Entorn de Desenvolupament
- Programa Hello World
- Sintaxi i Estructura Bàsiques
Mòdul 2: Tipus de Dades i Variables
Mòdul 3: Flux de Control
Mòdul 4: Funcions
- Introducció a les Funcions
- Arguments de Funció i Valors de Retorn
- Àmbit i Durada de les Variables
- Funcions Recursives
Mòdul 5: Arrays i Strings
Mòdul 6: Punteres
Mòdul 7: Estructures i Unions
Mòdul 8: Assignació Dinàmica de Memòria
Mòdul 9: Gestió d'Arxius
- Introducció a la Gestió d'Arxius
- Lectura i Escriptura d'Arxius
- Posicionament d'Arxius
- Gestió d'Errors en Operacions d'Arxius
Mòdul 10: Temes Avançats
- Directives del Preprocessador
- Arguments de Línia de Comandes
- Llistes d'Arguments Variables
- Multifil en C
Mòdul 11: Millors Pràctiques i Optimització
- Llegibilitat del Codi i Documentació
- Tècniques de Depuració
- Optimització del Rendiment
- Consideracions de Seguretat