1. 程式人生 > 實用技巧 >[C語言]變長函式引數和變長引數巨集

[C語言]變長函式引數和變長引數巨集

C++裡對於變化長引數已經有了較好的處理方案,這裡對C語言的變長引數進行一個簡答的總結。主要分為兩塊:函式和巨集。

函式的變長引數

常見於printf系列函式,以printf的實現為例:

int printf (const char *format, ...) {
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}

主要用到了va_list系列巨集,定義在stdarg.h標頭檔案中。
注意,va_start是把操作指標移動到了變長引數頭部,如果需要對變長引數操作多次,需要首先使用va_copy(dst,src)

對變長引數進行備份。

巨集的變長引數

巨集的變長引數可用於定義一個自定義附加資訊的assert:

#define vassert(expr, fmt, ...)                               \
    do {                                                      \
        if (!(expr)) {                                        \
            char *msg;                                        \
            asprintf(&msg, fmt, ##__VA_ARGS__);               \
            __assert_fail(msg, __FILE__, __LINE__, __func__); \
        }                                                     \
    } while (0)

這裡用到的是__VA_ARGS__巨集,C99中被標準化,編譯時自動替換為實際對應的引數集。
##的作用是正確處理變長引數為空的情況。