As macros stdarg
va_list, va_start, va_arg.
As macros stdarg é uma aula grátis de C Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C Academy inclui 4 aulas no total.
O que são funções variádicas?
Uma função variádica aceita uma quantidade variável de argumentos. Você já usou uma: printf pode receber qualquer quantidade de valores.
C permite que você escreva suas próprias funções usando as macros de <stdarg.h>.
#include <stdio.h>
int main(void) {
printf("%d %d %d\n", 1, 2, 3);
printf("%s\n", "any count of args");
return 0;
}As reticências
Você declara uma função variádica usando ... (as reticências) como último parâmetro.
Pelo menos um parâmetro nomeado deve vir antes dele, para que a função saiba onde começa a parte variável.
#include <stdio.h>
#include <stdarg.h>
void demo(int count, ...) {
printf("This function takes %d extra args\n", count);
}
int main(void) {
demo(3, 10, 20, 30);
return 0;
}Incluindo stdarg.h
Para ler os argumentos variáveis, você precisa de #include <stdarg.h>.
Esse cabeçalho define o tipo va_list e as macros va_start, va_arg e va_end.
#include <stdio.h>
#include <stdarg.h>
void show(int n, ...) {
va_list args;
va_start(args, n);
va_end(args);
printf("set up and cleaned up\n");
}
int main(void) {
show(2, 5, 6);
return 0;
}va_list e va_start
Declare uma variável va_list para acompanhar a posição atual. Em seguida, chame va_start(list, last), passando o último parâmetro nomeado.
Isso posiciona a lista no primeiro argumento variável.
#include <stdio.h>
#include <stdarg.h>
void first(int count, ...) {
va_list args;
va_start(args, count);
int value = va_arg(args, int);
printf("first variadic arg = %d\n", value);
va_end(args);
}
int main(void) {
first(1, 99);
return 0;
}va_arg: lendo valores
va_arg(list, type) retorna o próximo argumento e avança a lista. Você precisa informar o tipo exato a ser lido.
Cada chamada avança um argumento.
#include <stdio.h>
#include <stdarg.h>
void three(int n, ...) {
va_list args;
va_start(args, n);
int a = va_arg(args, int);
int b = va_arg(args, int);
int c = va_arg(args, int);
printf("%d %d %d\n", a, b, c);
va_end(args);
}
int main(void) {
three(3, 7, 8, 9);
return 0;
}va_end: limpeza
Sempre chame va_end(list) quando terminar a leitura. Ele realiza toda a limpeza necessária para a plataforma.
Esquecê-lo causa comportamento indefinido em alguns sistemas.
#include <stdio.h>
#include <stdarg.h>
int add_two(int dummy, ...) {
va_list args;
va_start(args, dummy);
int sum = va_arg(args, int) + va_arg(args, int);
va_end(args);
return sum;
}
int main(void) {
printf("%d\n", add_two(0, 4, 6));
return 0;
}Sabendo quantos argumentos há
As macros não conseguem informar quantos argumentos foram passados. Você precisa fornecer essa informação.
Uma abordagem comum é usar um parâmetro inicial de contagem, como em sum(3, a, b, c).
#include <stdio.h>
#include <stdarg.h>
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++)
total += va_arg(args, int);
va_end(args);
return total;
}
int main(void) {
printf("%d\n", sum(4, 1, 2, 3, 4));
return 0;
}Usando um valor sentinela
Outra forma de marcar o fim é usar uma sentinela: um valor especial de término que o chamador deve incluir, como -1 ou NULL.
Repita o laço até ler a sentinela.
#include <stdio.h>
#include <stdarg.h>
int sum_until_neg(int first, ...) {
va_list args;
va_start(args, first);
int total = first, v;
while ((v = va_arg(args, int)) != -1)
total += v;
va_end(args);
return total;
}
int main(void) {
printf("%d\n", sum_until_neg(10, 20, 30, -1));
return 0;
}Promoções padrão de argumentos
Os argumentos variádicos passam por promoções padrão: char e short tornam-se int, e float torna-se double.
Portanto, leia sempre inteiros pequenos como int e números de ponto flutuante como double com va_arg.
#include <stdio.h>
#include <stdarg.h>
void show_double(int n, ...) {
va_list args;
va_start(args, n);
double d = va_arg(args, double);
printf("%.2f\n", d);
va_end(args);
}
int main(void) {
show_double(1, 3.5f);
return 0;
}Copiando uma va_list
Se precisar percorrer os argumentos duas vezes, use va_copy(dest, src) para duplicar a lista antes de fazer a leitura.
Você não pode reutilizar uma va_list após va_end sem reiniciá-la usando va_start.
#include <stdio.h>
#include <stdarg.h>
void twice(int n, ...) {
va_list a, b;
va_start(a, n);
va_copy(b, a);
printf("%d %d\n", va_arg(a, int), va_arg(b, int));
va_end(a);
va_end(b);
}
int main(void) {
twice(1, 42);
return 0;
}Calculando uma média
Combinando o padrão de contagem com a leitura de números de ponto flutuante, podemos calcular a média de uma lista de números passados de forma variádica.
#include <stdio.h>
#include <stdarg.h>
double average(int count, ...) {
va_list args;
va_start(args, count);
double sum = 0;
for (int i = 0; i < count; i++)
sum += va_arg(args, double);
va_end(args);
return sum / count;
}
int main(void) {
printf("%.2f\n", average(3, 2.0, 4.0, 6.0));
return 0;
}Verificação rápida
Teste sua compreensão das macros de stdarg.
Recapitulação
Você aprendeu o mecanismo variádico:
- Declare usando
...depois de pelo menos um parâmetro nomeado. va_start(list, last)inicia,va_arg(list, type)lê eva_end(list)faz a limpeza.- As macros não sabem a quantidade — use um parâmetro de contagem ou uma sentinela.
- Tenha atenção às promoções padrão: leia inteiros pequenos como
inte números de ponto flutuante comodouble.
Perguntas Frequentes
A aula “As macros stdarg” é grátis?
Sim — o texto completo de “As macros stdarg” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C Academy, atualize para CoddyKit PRO. O curso de C Academy inclui 4 aulas no total.
O que vou aprender em “As macros stdarg”?
va_list, va_start, va_arg. Você pratica C Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C Academy?
Nenhuma experiência prévia é necessária. C Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “As macros stdarg”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C Academy?
Sim. Cada aula de C Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- As macros stdarg
- Escrevendo funções semelhantes a printf
- Questões de segurança de tipos
- Exemplos práticos