C言語で配列の要素数を求めるには、sizeof演算子を使用します。
組み込みマイコンでは、要素数をあらかじめ定義して使用するため、#defineで要素数を定義すれば、sizeof演算子を使用する必要はありません。
具体的な使用方法を見ていきましょう。
配列の要素数を定義する
組み込みマイコンでは、ほぼこれでしょう。定義されていれば、わざわざsizeof演算子を用いる必要はないですからね。
組み込みマイコンでは処理速度が求められますので、余計な演算はなるべく省いていきます。
#include <stdio.h> #define MAX_ARRAY_NUM 5 void main(void) { short data[MAX_ARRAY_NUM] = {10, -5, 100, 49, -1}; printf("配列の要素数は%d\n", MAX_ARRAY_NUM); }
これだけです。要素数は#defineで定義されているので、計算する必要がありません。
次にsizeof演算子を使用する方法を解説します。
配列の要素数をsizeof演算子を用いて求める
sizeof演算子は、配列や型などのサイズ(使用しているメモリ領域)を求める演算子です。
例えば、配列を次のように宣言し、sizeof演算子を使用したら、どういう値を返すか見ていきましょう。
#include <stdio.h> void main(void) { short data1[5]; long data2[10]; char data3[4]; prinntf("data1のsizeofの値:%d\", sizeof(data1)); prinntf("data2のsizeofの値:%d\", sizeof(data2)); prinntf("data3のsizeofの値:%d\", sizeof(data3)); }
結果は
data1のsizeofの値:10 data2のsizeofの値:40 data3のsizeofの値:4
となります。配列のサイズは要素数×配列の型のサイズになるため、sizeof演算子を用いると、上記の結果になります。
したがって、配列の要素数を求めようとしたら、もうおわかりですね。
配列のサイズを配列の型のサイズで割れば、要素数が求められます。
#include <stdio.h> void main(void) { short data1[5]; long data2[10]; char data3[4]; prinntf("data1のsizeofの値:%d\", sizeof(data1)); prinntf("data2のsizeofの値:%d\", sizeof(data2)); prinntf("data3のsizeofの値:%d\", sizeof(data3)); prinntf("data1の要素数:%d\", sizeof(data1)/sizeof(short)); prinntf("data2の要素数:%d\", sizeof(data2)/sizeof(long)); prinntf("data3の要素数:%d\", sizeof(data3)/sizeof(char)); }
結果は
data1のsizeofの値:10 data2のsizeofの値:40 data3のsizeofの値:4 data1の要素数:5 data2の要素数:10 data3の要素数:4
となり、配列の要素数が求められることがわかります。
これが構造体変数だとしてもやり方は同じです。
sizeof(構造体の変数の先頭アドレス) / sizeof(構造体の型)
ただし、配列を関数で渡すことはできないので、関数側ではsizeof演算子では配列の要素数を求めることはできません。配列の要素を関数側で使用するには、配列の先頭アドレスのポインタと要素数を引数として渡してやる必要があります。
組み込みマイコンで、配列の要素数を用いる場面
組み込みマイコンで、配列の要素数を用いる場面としては、主に2つあります。
・配列の要素数だけfor文やwhile文を回すためのループ回数として使用
・配列へ値の代入をするときに、要素数を超えていないかのチェックに使用
どちらも、プログラムが暴走しないように、かつ、最小の実行処理をするためです。
とくに2つ目は配列をリングバッファと呼ばれるバッファとしてい扱うとき、配列の要素数いっぱいまで、データを入れたら、0番目に戻して、データを入れていくということは普通に行われます。
そのときに、配列の要素数がわかっていないと、0に戻せないのはわかりますよね。組み込みマイコンではmain関数自体が無限ループになっているので、配列の領域も必要最小限に抑えたいわけです。
通信データの取り込みなんかも、リングバッファが用いられます。通信データそのものは割り込みルーチンで取り込まれるため、ある程度、バッファにためておく必要があります。
それをメインルーチンで読み出して処理するのですが、メインルーチンで読み出すまでに割り込みルーチンでどれだけデータの格納が行われるかで、配列の要素数を決めるわけです。
余裕を見て確保しますが、不必要に確保することもしません。なぜなら、メモリに制約があるからです。
メインルーチンで読み出してしまったデータは不要になるので、上書きしていくわけなんですね。そのために、配列の要素数が必要不可欠になるわけです。
まとめ
配列の要素数の求め方について、説明しました。
1つは、要素数そのものを定義してしまう。もう1つは、sizeof演算子を使って、要素数を求めるというものでしたね。
注意点は2つありましたね。
・sizeof演算子を用いて要素数を求める場合は、配列の型のサイズで割るということを忘れないこと。
・配列を関数に渡すことはできないので、配列の先頭アドレスのポインタと配列の要素数を渡すのを忘れないこと。
これさえ気をつければ、配列の要素数を求めることは、難しくないと思います。
要素数を定義してしまえば、わざわざ、演算しなくてもいいので、計算が面倒だと思うなら、要素数を定義すればいいと思います。
組み込みマイコンでは、基本的に定義して使うので、sizeof演算子で求められるということだけ、覚えておけば、それほど苦労することはありません。 配列の要素数の求め方は以上になります。この部分は、難しくないので、最速でマスターしましょう!