このページの解説は C99 をベースとしています。
以下は目次です。
配列が定義されているとして、実行時に、その配列の要素数を知るにはどうすればいいでしょうか。
たとえば、以下のような2つの配列に対して、それぞれ 10 と 5 という値を得たいということです。
int array1[10];
int array2[] = {0, 1, 2, 3, 4};
sizeof演算子(第19章)を使います。
配列は、すべての要素が隙間なく連続しており、要素以外に余計なものが含まれていませんから、配列全体の大きさと、配列の要素1個分の大きさを、sizeof演算子を使ってそれぞれ取得し、「配列全体の大きさ÷要素1個分の大きさ」とすれば、要素数を算出できます。
#include <stdio.h>
int main(void)
{
int array1[10];
int array2[] = {0, 1, 2, 3, 4};
("%zu\n", sizeof(array1) / sizeof(array1[0]));
printf("%zu\n", sizeof(array2) / sizeof(array2[0]));
printf}
実行結果:
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};
("%zu\n", SIZE_OF_ARRAY(array1));
printf("%zu\n", SIZE_OF_ARRAY(array2));
printf}
実行結果:
10
5
この方法は、ポインタに対して使うことができないことに注意してください。特に注意が必要なのは、関数の引数として配列を渡す(渡したつもりになっている)ときです。
#include <stdio.h>
#define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof(array[0]))
void print_array_size(const int* array)
{
("%zu\n", SIZE_OF_ARRAY(array));
printf}
int main(void)
{
int array1[10];
int array2[] = {0, 1, 2, 3, 4};
(array1);
print_array_size(array2);
print_array_size}
実行結果:
1
1
この場合、配列はポインタ(配列の先頭を指すポインタ)に変換されています。ポインタを sizeof演算子に渡したら、ポインタの大きさが返ってくるだけなので、配列全体の大きさを知ることはできません。
このように、配列をポインタとして扱っているときは、要素数を求めることができないので、malloc関数等を使って、 動的に確保された配列の要素数を求めることもできません。
return 0;
を削除(C言語編全体でのコードの統一)VisualStudio 2013 の対応終了。
「VisualC++」という表現を「VisualStudio」に統一。
「サイズ」という表記について表現を統一。 型のサイズ(バイト数)を表しているところは「大きさ」、要素数を表しているところは「要素数」。
コンパイラの対応状況について、対応している場合は明記しない方針にした。
clang 3.7 (Xcode 7.3) を、Xcode 8.3.3 に置き換え。
新規作成。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |