配列の要素数を求める | Programming Place Plus C言語編 逆引き

トップページC言語編逆引き

このページの概要 🔗

このページの解説は C99 をベースとしています

以下は目次です。

目的 🔗

配列が定義されているとして、実行時に、その配列の要素数を知るにはどうすればいいでしょうか。

たとえば、以下のような2つの配列に対して、それぞれ 10 と 5 という値を得たいということです。

int array1[10];
int array2[] = {0, 1, 2, 3, 4};

方法①(sizeof演算子を活用する) 🔗

sizeof演算子(第19章)を使います。

配列は、すべての要素が隙間なく連続しており、要素以外に余計なものが含まれていませんから、配列全体の大きさと、配列の要素1個分の大きさを、sizeof演算子を使ってそれぞれ取得し、「配列全体の大きさ÷要素1個分の大きさ」とすれば、要素数を算出できます。

#include <stdio.h>

int main(void)
{
    int array1[10];
    int array2[] = {0, 1, 2, 3, 4};

    printf("%zu\n", sizeof(array1) / sizeof(array1[0]));
    printf("%zu\n", sizeof(array2) / sizeof(array2[0]));
}

実行結果:

10
5

sizeof演算子が返す値は、size_t型という符号無し整数型です。printf関数で出力する際には、“%d” や “%u” ではなく、“%zu” を使いましょう。

“%zu” は C99規格で追加されました。これが使えない環境では、“%lu” などで代用することになります。

配列の要素数を求めたい場面はよくあるので、汎用的に使えるように、関数形式マクロ(第28章)を定義しておくと良いでしょう。「注意」のところで説明する理由から、関数にすることはできず、マクロにせざるを得ません。

#include <stdio.h>

#define SIZE_OF_ARRAY(array)    (sizeof(array)/sizeof(array[0]))

int main(void)
{
    int array1[10];
    int array2[] = {0, 1, 2, 3, 4};

    printf("%zu\n", SIZE_OF_ARRAY(array1));
    printf("%zu\n", SIZE_OF_ARRAY(array2));
}

実行結果:

10
5

注意 🔗

この方法は、ポインタに対して使うことができないことに注意してください。特に注意が必要なのは、関数の引数として配列を渡す(渡したつもりになっている)ときです。

#include <stdio.h>

#define SIZE_OF_ARRAY(array)    (sizeof(array)/sizeof(array[0]))

void print_array_size(const int* array)
{
    printf("%zu\n", SIZE_OF_ARRAY(array));
}

int main(void)
{
    int array1[10];
    int array2[] = {0, 1, 2, 3, 4};

    print_array_size(array1);
    print_array_size(array2);
}

実行結果:

1
1

この場合、配列はポインタ(配列の先頭を指すポインタ)に変換されています。ポインタを sizeof演算子に渡したら、ポインタの大きさが返ってくるだけなので、配列全体の大きさを知ることはできません。

このように、配列をポインタとして扱っているときは、要素数を求めることができないので、malloc関数等を使って、 動的に確保された配列の要素数を求めることもできません。


参考リンク 🔗


更新履歴 🔗

 VisualStudio 2013 の対応終了。

 「VisualC++」という表現を「VisualStudio」に統一。

 「サイズ」という表記について表現を統一。 型のサイズ(バイト数)を表しているところは「大きさ」、要素数を表しているところは「要素数」。

 コンパイラの対応状況について、対応している場合は明記しない方針にした。

 clang 3.7 (Xcode 7.3) を、Xcode 8.3.3 に置き換え。

 新規作成。



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る