新人技術者のためのロジカル・シンキング入門(2) ―― プログラミングにおける良いデータ構造
【2】外部変数に対する解決策(1/2)
では,ここから解決策を考えることにしましょう.外部変数が無秩序に使われているプログラムがあったとして,それをどのように改善すればよいのでしょうか.
● コーディング規約だけでは焼け石に水
すぐに思いつく管理方針としては,
- 外部変数はかならず引き数にとる
- コーディング規約を定める
といったことが挙げられそうです.しかしこれは,たいていの場合,焼け石に水となってしまいます.
実は,外部変数の無秩序な使用からくる混乱が生じていた場合,まちがいなく設計の方針を立てるレベルで外部変数の管理方針が定まっていなかった点に根本の原因があるからです.このような場合,単なるコーディング規約の採用では混乱は回避できません.たとえルールを定めたとしても,外部変数の管理方針が定まっていなければ,ルールを破ってコードを書く者が現れるからです.そして,遵守を徹底してもプログラムが見通しの悪いものになる点は改善されないのです.
● 解決にはデータ構造の把握が不可欠
つまり,開発しようとする機能ブロックまたはシステムではどのような性質のデータを扱っており,それをC言語あるいはそのほかの言語で実装する場合にどの種類の変数を使えばよいのかということが,設計の段階で方針として定まっており,それにのっとってコーディングされていなければならないのです.以下に,解決策の具体例として筆者がよく用いるデータの管理方針を紹介します(図3).プログラム言語はC言語を用いることとします.
まず,どのようなデータ構造がそのモジュールにとって必要とされるのかを考える.そして,用いる言語(C言語など)でどのようなデータ種別を使い分けると目的が果たせるのかを調べる.その後,データ構造を設計レベルで確立する.
外部変数の管理方針を決める前に,まずプログラムで扱われるデータ領域にはどのような種類が存在するのかを考えていくことにします.システム固有の条件も加味したうえで,データにはどのような種別があるのかを考え,適した管理方針を模索していきたいと思います(表1).
大項目 | 中項目 | 小項目 | 解説 |
プログラム | テキスト | ― | |
データ | 値を保持 | スタティック | リード/ライト |
テーブル | リードのみ | ||
使い捨て | ダイナミック | 関数間で共用 | |
ローカル変数 | 1関数のみで使用 |
● まず,値を保持するデータ領域かどうかで分類する
前述したように,外部変数の特徴の一つに「値を保持できる」というものが挙げられます.一方,ローカル変数などは関数を抜けてしまえば値が保持されず,使い捨てとなる領域です.
開発対象のモジュール全体を考えた場合,モジュールのインターフェースとなる関数を抜けても値が保持されなければならないようなデータは,外部変数などの領域をとる必要があります.つまり,データの領域は大きく「使い捨て」と「値を保持」の二つの部分に分けられます(表1の中項目).このどちらに分類されるかで,どのようなデータ種別を用いなければならないかが決まります.一般に,使い捨てのデータ領域のほうが,その重要性と扱いをまちがったときの混乱が大きく,特別な配慮が必要となります.
● 値保持データはスタティックとテーブルに分かれる
次に,値を保持するデータについてさらに詳細を追ってみることにしましょう.リードのみ(読み取り専用)で,値の更新を予定しないデータがプログラムに用いられることがあります.これは,組み込みソフトウェアでは「テーブル」と呼ばれるデータ領域です.例えば,三角関数の値のように,いちいちプログラムで計算すると処理量がむだなため,あらかじめ計算結果をテーブル引きできるようにしておく場合などに用いられるものです.
このテーブルとは逆に,リード/ライトがともに行われるデータもあります.例えば,ライブラリ・モジュールの最上位関数が呼び出し元のプログラムから呼び出されるたびに値を更新して保持しておかなければならないようなデータです.このようなデータをここでは「スタティック・データ」と呼び,テーブルとは区別しておくことにします(スタティック・データを「RAM領域」,テーブルを「ROM領域」と呼ぶこともある).
これらがどれだけの大きさを持つかが,組み込みシステム開発では重要になります.管理方針が定まっていなければ,大きさの予想さえ行えません.