va_copy (C99)

可変長引数 (variable arguments) を初期化します.

#include <stdarg.h>
void va_copy(
    va_list dest,
    va_list src
);

va_copy マクロは,dest に va_start マクロを適用し,それに続いて (src のその時点の状態に達するために使った順序と同じ順序で) va_arg マクロを使った場合と同じ規則に従って,dest を src のコピーとして初期化します.

va_copy マクロは,dest に対して va_end マクロを呼び出すことなく,その dest を最初期化する目的で呼び出してはいけません.

C言語サンプルプログラム

/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>

/* functions */
void sum_product(double *, double *, int n, ...);

/* main */
int main(void) {
    double sum, product;

    /* 総和と総乗を求める */
    sum_product(&sum, &product, 4, 1.0, 2.0, 3.0, 4.0);

    printf("総和: %.1f\n", sum);
    printf("総乗: %.1f\n", product);

    return EXIT_SUCCESS;
}

/**
 * @brief 総和と総乗を求める
 * @param[OUT] sum 総和
 * @param[OUT] product 総乗
 * @param[IN] n 引数の数
 * @param[IN] ... 可変長引数
 */
void sum_product(double *sum, double *product, int n, ...) {
    va_list ap;
    va_list dest;
    int i;

    va_start(ap, n);
    va_copy(dest,ap);

    *sum = 0.0;
    *product = 0.0;

    /* 総和 */
    for ( i = 0; i < n; i++ ) {
        *sum += va_arg(ap, double);
    }

    /* 総乗 */
    *product = va_arg(dest, double);
    for ( i = 1; i < n; i++ ) {
        *product *= va_arg(dest, double);
    }

    va_end(ap);
    va_end(dest);
}

実行例

サンプルプログラムの実行結果は以下のようになります.

総和: 10.0
総乗: 24.0

Cプログラマの必読書

たくさんあるC言語関連の書籍の中でも特に役に立った本です.よかったら参考にしてみてください.

C実践プログラミング 第3版

C言語の実践的参考書.少々値段は張りますが初心者を脱しようとしている人は絶対に読むべきです.
文法だけでなく,コーディングスタイルやデバッグなど文字通り「実践的」なことが書かれているので非常にためになります. オライリーの本は,読みにくい本が多いのですが本書はとても読みやすくオススメです.


C言語ポインタ完全制覇 (標準プログラマーズライブラリ)

ポインタの解説書としては最高の書籍です.
この1冊でポインタを完全に理解することができます.全くの初学者が読むには敷居が高いですが,入門書を読み終えた後に読むと非常に有益です.