array の解説と実装リファレンス
【概要】
Arduino(C/C++)における「array(配列)」は、同一のデータ型を持つ複数の要素をメモリ上の連続した領域に配置するデータ構造です。特定のインデックス(添字)を用いて、各要素への高速なアクセスを実現します。組み込みシステムにおいては、センサーデータのバッファリング、通信プロトコルのパケット処理、信号処理のためのルックアップテーブルなど、効率的なデータ管理の基礎として不可欠な要素です。
【仕様】
基本定義
- データ型:
int,float,char,byte,uint8_t等、任意の基本型または構造体。 - インデックス: 0から始まる整数値。
- サイズ計算: 配列全体に対する要素数の取得は、
sizeof(array) / sizeof(array[0])を用いて算出する。
初期化と宣言
int sensorReadings[5] = {10, 20, 30, 40, 50}; // 静的な初期化
byte buffer[10]; // 未初期化(内容は不定)
【技術的特徴】
メモリ配置とアクセス速度
- 計算量: 配列要素へのアクセスは O(1)であり、インデックス計算のみでメモリのアドレスを特定するため、非常に高速である。
- ポインタとの関係: 配列名は、メモリ上の最初の要素を指すポインタとして評価される。そのため、ポインタ演算を用いることで要素間の移動を効率的に記述できる。
- 連続性: 要素はメモリ上で連続して配置されるため、空間局所性が高く、キャッシュ効率(より高度なマイコンにおいて)やシリアルなデータ転送に適している。
スタックとメモリセグメント
- Arduino(特にAVRマイコン)において、静的に定義された配列はデータセグメントまたはスタックに配置される。
const修飾子を付与した配列は、設計によってはPROGMEMを用いてRAMを消費せずにFlashメモリ上に配置することが可能であり、リソース制約のある環境では重要な最適化手法となる。
【注意点】
境界外アクセス(Buffer Overflow)
- C/C++標準の配列には、範囲チェック(Bounds Checking)の機能がない。指定したインデックスが配列のサイズを超えている場合、意図しないメモリ領域を破壊、または読み取るため、システムが不安定化する原因となる。
リソース制約(SRAM)
- Arduino Uno等の低メモリ環境では、巨大な配列の宣言はスタックオーバーフローを引き起こす。配列のサイズは、使用可能なSRAM容量を考慮し、最小限に設計する必要がある。
可変長配列(VLA)
int arr[n];のように実行時にサイズを決定する可変長配列は、コンパイラや標準規格によってはサポートされない、あるいはスタックを過度に消費する可能性がある。動的なサイズ変更が必要な場合は、std::vector(メモリ管理に注意)や動的メモリ確保(malloc/new)を検討するが、組み込みではメモリ断片化を防ぐため、あらかじめ最大サイズを確保する静的配列の使用が推奨される。
【サンプルコード】
#include <Arduino.h>
// センサーデータの移動平均用バッファ(静的配列)
const int BUFFER_SIZE = 8;
byte dataBuffer[BUFFER_SIZE] = {0};
int bufferIndex = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
// 擬似的なデータ取得
byte newData = analogRead(A0) % 256;
// 配列への格納(リングバッファ的な動作)
dataBuffer[bufferIndex] = newData;
bufferIndex = (bufferIndex + 1) % BUFFER_SIZE;
// 配列の平均値を計算
long sum = 0;
for (int i = 0; i < BUFFER_SIZE; i++) {
sum += dataBuffer[i];
}
Serial.print("Average: ");
Serial.println(sum / BUFFER_SIZE);
delay(100);
}
【活用例】
- 移動平均フィルタ(Moving Average Filter):
センサーのノイズ除去のため、直近 N 個のサンプルを配列に保持し、平均値を算出する。 - 通信プロトコルバッファ:
UARTやSPI通信において、受信したバイナリデータを一旦配列に蓄積し、ヘッダーとペイロードを解析する。 - ルックアップテーブル(LUT):
複雑な三角関数や対数計算をリアルタイムで実行する代わりに、あらかじめ計算済みの値を配列に格納しておき、インデックス参照で取得することでCPU負荷を軽減する。


コメント