C言語をやっていくうえで、配列の中から最大値や最小値を取得したい場面は多々あると思います。
しかし、簡単に効率よく見つけるような方法はなく、配列のデータを順に見ていくしかありません。
ただし、配列のデータがソートされているようなものであるならば、配列の先頭や最後のデータを取得すればいいだけなので、ソートされているときに限っては簡単に見つけることができます。
組み込みマイコンの世界でも、最大値や最小値を取得する場面はありますので、身につけておくべき内容です。
配列に数値がランダムで格納されているときの最大値・最小値の見つけ方
冒頭でも述べたように、ランダムに格納されている場合は配列の先頭、もしくは後ろから順にデータを見ていくしかありません。泥臭いですが、これが一番確実に見つけられる方法です。
#inclue <stdio.h> #define MAX_INDEX 100 void main(void) { short data[MAX_INDEX] = {}; short max_num; short min_num; short i; dataに数値を設定する処理のコードは適宜対応すること。 /* 比較するデータの初期化 */ /* 最終的には最大値・最小値が格納される */ max_num = data[0]; min_num = data[0]; for (i = 1; i < MAX_INDEX; i++) { /* 現在の最大値より大きければ、その値を新たな最大値に設定 */ if (max_num < data[i]) { max_num = data[i]; } /* 現在の最小値より小さければ、その値を新たな最小値に設定 */ if (min_num > data[i]) { min_num = data[i]; } } 以降、適宜処理を追加する。 }
最初に、最大値も最小値もdata[0]の値で初期化しています。こうしておかないと、最初の比較で不定な値と比較してしまうので、得られる結果が期待していたものと違ってしまう可能性があります。
最大値、最小値にdata[0]の値を設定したので、for文の開始は1からになっています。なので、最初はdata[0]とdata[1]の値を比較していることになります。
別に0からfor文を開始してもいいのですが、全く意味のない比較を1回余計にしてしまうだけなので、適切な値からfor文を開始しています。
ソーティングをして、実行処理を増やすくらいなら、このやり方で十分でしょう。
配列に数値がランダムに格納されているものを昇順・降順に並べ替える
組み込みマイコンでは、配列のデータを昇順や降順に並べ替えることは、ほぼないのですが、配列の扱いということで軽く解説しておきます。
泥臭くやるには、バブルソートと呼ばれるやり方が一番簡単です。ただし、比較回数が多いので処理は遅いです。
大きい順に並べ替えるやり方で、こんな感じです。
#inclue <stdio.h> #define MAX_INDEX 100 void main(void) { short data[MAX_INDEX] = {}; short tmp; short i, j; dataに数値を設定する処理のコードは適宜対応すること。 /* データを一つずつ比較して入れ替える */ for (i = 0; i < MAX_INDEX; i++) { for (j = MAX_INDEX; j > i; j--) { /* 隣の値と比較し、隣の値のほうが大きければ、入れ替える */ if (data[j - 1] < data[j]) { tmp = data[j]; data[j] = data[j - 1]; data[j - 1] = tmp; } } } 以降、適宜処理を追加する。 }
やっていることは配列の最大値を求めて、配列の先頭に格納し、その後、先頭の配列の値を除外した配列の中で、最大値を求め、配列の2番目に格納するということの繰り返しを配列のサイズ分行っています。
組み込みマイコンの世界では思い処理はなるべく避けるようにするので、このようなソートをすることはしないわけです。
組み込みマイコンで配列の最大値・最小値を扱う場面
組み込みマイコンで配列の最大値・最小値を扱う場面ですが、主に異常検出に使います。
エレベータでいいますと、ある一定時間の間に速度の最小値と最大値が想定速度からある閾値を超えていたら、異常とみなすという感じです。
速度を監視しておかないと、大変なことになるのはお分かりいただけると思います。
もちろん、ハードウェアで一定速度以上になると停止させる機器が備わっていますので、普段の速度から極端に外れた速度になることはありません。
ハードウェアで異常を検出する前に、ソフトウェアでも異常を検出して、エレベータを安全に停止させて、乗客を降ろすように、安全設計しています。
ハードウェアで停止する場合は、急停止となってしまうので、乗客に怪我をさせてしまうかもしれません。そのため、なるべくソフトウェアで異常を検出して停止させるようにしています。
そうすることで、人も物も守ることができるのです。
配列の最大値・最小値の取得方法からかなり逸れた話をしてしまいましたが、もし、あなたが組み込みマイコンのプログラマーを目指すのであれば、そのようなことも考えて設計していかなくてはならないので、軽くですが、お話しました。
まずは、C言語の基本的な部分を吸収していっていただければと思います。
まとめ
配列の最大値・最小値を取得するには、配列のデータを順番に見ていくしかないとお話しました。
ソーティングすれば、簡単に配列の最大値・最小値を取得できることもお話しました。
しかし、組み込みマイコンでは余計な処理はしないように設計するため、順番に配列のデータを見ていき、最大値・最小値を取得する方法を用いるのが通例です。
エレベータの制御の世界でお話しすると、1msec単位、つまり1/1000秒単位の世界です。ほんの少しの処理の遅れが、位置ずれを起こしたりする非常にシビアな世界です。
ほんの少しのずれでクレームになる日本では、プログラムの見やすさより、処理速度が優先されるため、どうしても、後々メンテナンスがしにくい状態であります。
次世代の組み込みマイコンのプログラマーが困らないように教育や情報発信をしていきたいと思っています。