0Pricing
C Academy · Aula

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ê e va_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 int e números de ponto flutuante como double.

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

  1. As macros stdarg
  2. Escrevendo funções semelhantes a printf
  3. Questões de segurança de tipos
  4. Exemplos práticos
← Voltar para C Academy