ホームC言語Tips集関数 ≫ ポインタ渡しを利用して関数から値を取得する

C言語Tips集 - ポインタ渡しを利用して関数から値を取得する

C言語では,関数の引数の受渡しにポインタを使用することで,参照渡し (call-by-reference) と同じ動作をさせることができます.これをポインタ渡しと呼びます.

ポインタ渡しを行うには,呼び出される側の関数 (callee) の仮引数にポインタ変数を用意し,呼び出し側の関数 (caller) の実引数に変数のアドレスを指定します.

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

以下に配列の合計,平均,分散,標準偏差,最大,最小を求める関数を定義し,ポインタ渡しによって,それぞれの値を呼び出し側の関数に返すサンプルプログラムを示します.

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

/* functions */
int GetDataInfo(const double *data, int n,
        double *sum, double *avg, double *var,
        double *dev, double *max, double *min);

/* main */
int main(void) {
    double data[5] = {2.0, 5.0, 8.0, 1.0, 5.0};
    double sum, avg, var, dev, max, min;
    int count;

    /* ポインタ渡しを利用して合計,平均,分散,標準偏差,最大,最小を取得 */
    count = GetDataInfo(data,5,&sum,&avg,&var,&dev,&max,&min);
    if ( count > 0 ) {
        printf("合計: %.2f\n", sum);
        printf("平均: %.2f\n", avg);
        printf("分散: %.4f\n", var);
        printf("標準偏差: %.4f\n", dev);
        printf("最大: %.2f\n", max);
        printf("最小: %.2f\n", min);
    }
    return EXIT_SUCCESS;
}

/*
 * 配列に格納されている値の合計,平均,分散,標準偏差,最大,最小を取得
 * @param[in] data 入力配列
 * @param[in] n 配列の要素数
 * @param[out] sum 合計
 * @param[out] avg 平均
 * @param[out] var 分散
 * @param[out] dev 標準偏差
 * @param[out] max 最大
 * @param[out] min 最小
 * @retval 処理した要素の数 正常終了時
 * @retval 0 エラー発生時
 */
int GetDataInfo(const double *data, int n,
        double *sum, double *avg,double *var, 
        double *dev, double *max, double *min) {

    int i, count = 1;
    double sqsum;

    if ( n <= 0 ) return 0;

    /* 初期値セット */
    *max = *min = data[0];
    *sum = data[0];
    sqsum = data[0] * data[0];

    for (i = 1; i < n; i++) {
        /* 最大, 最小 */
        if ( *max < data[i] ) *max = data[i]; /* 最大 */
        if ( *min > data[i] ) *min = data[i]; /* 最小 */

        /* 合計 */
        *sum += data[i]; /* 和 */
        sqsum += data[i] * data[i]; /* 平方和 */

        count++;
    }

    /* 平均, 分散, 標準偏差 */
    *avg = *sum / (double)n; /* 平均 */
    *var = sqsum / (double)n - (*avg * *avg); /* 分散 */

    if ( *var < 0.0 ) *var = 0.0;
    *dev = sqrt(*var); /* 標準偏差 */

    return count;
}

実行例

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

合計: 21.00
平均: 4.20
分散: 6.1600
標準偏差: 2.4819
最大: 8.00
最小: 1.00

Cプログラマの必読書

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

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

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


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

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

関数の作成と呼び出し