Course Content
Programming in C
About Lesson

As we have already seen, printf can process variable-length argument list. Let’s try to implement to simpler version of printf.

#include <stdarg.h>

void print(char *format, ...)
{
  va_list ptr;
  char *p, *s; 

  va_start(ptr, format);  /* make ptr point to first unnamed arg */
  for (p = format; *p; p++) {
    if (*p != '%') {
      putchar(*p);
    } else {
      switch (*++p) {
        case 'd':
          printf("%d", va_arg(ptr, int));
          break;
        case 'f':
          printf("%f", va_arg(ptr, double));
          break;
        case 's':
          for (s = va_arg(ptr, char *); *s; s++)
            putchar(*s);
          break;
        default:
          putchar(*p);
          break;
      }   
    }   
  }
  va_end(ptr);  /* clean up */
}

Ellipsis(…) in the argument list means that the number of types of arguments may vary. This can only appear at the end of an argument list.

The type va_list is used declare a variable (argument pointer) that will refer to each argument in turn.
The macro va_start initialises the argument pointer ptr to point to the first unnamed argument. It must be called once before ptr is used. There must be one named argument. The last named argument is used by va_start for initialisation.
Calling va_arg returns one argument and steps the argument pointer to the next. va_arg uses a typename to determine what type to return and how big a step to take.
va_end does the necessary cleanup at the end, and must be called before the function returns.

All these macros: va_list, va_start, va_arg and va_end are contained in the header file “stdarg.h”.

Scroll to Top