ホームC言語Tips集関数 ≫ 関数から配列の先頭アドレスを返す

C言語Tips集 - 関数から配列の先頭アドレスを返す

C言語ではローカル変数として宣言した配列の先頭アドレスを関数から返すことはできません. 正確にいえば返すことは可能ですが,関数から抜けた時点でスタックフレーム (stack frame) 上の変数の値は不定になってしまいます. これを回避するには,以下の 3 種類の方法があります.

  • 引数から配列の先頭アドレスを受け取り,それを戻り値とする
  • 配列をグローバル変数として宣言する
  • 配列を static 記憶クラス指定子をつけて宣言する

呼び出し側の関数 (caller) で宣言されたローカル変数は,呼び出し側の関数が終了するまで確保されます.したがって,呼び出され側の関数 (callee) が終了しても変数は不定になりません. また,グローバル変数,もしくは static 記憶クラス指定子をつけて宣言された変数は,静的領域 (static area) に確保されます. 静的領域に確保された変数は,原則的にプログラムの終了時まで確保され続けます.したがって,この場合もまた,呼び出され側の関数が終了しても変数は不定になりません.

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

以下に関数から配列の先頭アドレスを返すサンプルプログラムを示します.

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

/* functions */
int *ReturnArray01(int *array);
int *ReturnArray02(void);
int *ReturnArray03(void);

/* global variables */
int g_array[5];

/* main */
int main(void) {
    int i;
    int array[5];
    int *array01;
    int *array02;
    int *array03;

    /* 関数から配列の先頭アドレスを返す */
    array01 = ReturnArray01(array);
    array02 = ReturnArray02();
    array03 = ReturnArray03();

    /* 結果を表示 */
    printf("array01 array02 array03\n");
    printf("------- ------- -------\n");
    for ( i = 0; i < 5; i++ ) {
        printf("%7d %7d %7d\n",array01[i],array02[i],array03[i]);
    }

    return EXIT_SUCCESS;
}

/**
 * 配列に値をセットする
 * @param[in,out] array 配列の先頭アドレス
 * @return 配列の先頭アドレス
 */
int *ReturnArray01(int *array) {
    int i;
    for ( i = 0; i < 5; i++ ) {
        array[i] = i + 1;
    }
    return array;
}

/**
 * 配列に値をセットする
 * @return 配列の先頭アドレス
 */
int *ReturnArray02(void) {
    int i;
    static int array[5];

    for ( i = 0; i < 5; i++ ) {
        array[i] = i + 1;
    }
    return array;
}

/**
 * 配列に値をセットする
 * @return 配列の先頭アドレス
 */
int *ReturnArray03(void) {
    int i;

    for ( i = 0; i < 5; i++ ) {
        g_array[i] = i + 1;
    }
    return g_array;
}

実行例

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

array01 array02 array03
------- ------- -------
      1       1       1
      2       2       2
      3       3       3
      4       4       4
      5       5       5

Cプログラマの必読書

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

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

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


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

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

関数と配列