プロローグ
これからCプログラミングをはじめる人へ


 本特集では,Cの文法をある程度理解した初心者を対象として,Cプログラミングに役立つテーマを取り上げて説明します.

筆者がプログラムをはじめたころ

 筆者がこの仕事にかかわりはじめたころは8ビットCPUであるZ80の全盛期で,簡単なテストプログラムは機械語で打ち込んで動作させることもありました.機械語はCPUが直接理解する言語です.0と1で表現され,通常は8進数や16進数で表示します.この機械語は普通の人間には理解できないため(中には機械語がすべて頭に入っている人もいたが),実際のプログラムは人間が理解しやすいアセンブリ言語で記述しました.通常はマクロ機能をもったマクロアセンブラで記述して,それをアセンブルして機械語に落とし,ROM化して,デバッグするといった手順を踏んでいました.

 アセンブリ言語(のニーモニック)と機械語は基本的には1対1で対応するため,デバッグをしていく過程で勝手に機械語が頭に入ってきて,間違った個所の修正を機械語で行ったりもしたものです.

 機械語やアセンブリ言語はCPUに固有のもので,CPUごとに違うため,68000や8086といった高機能なCPUが出てきても,簡単に乗り換えることはできませんでした.

組み込みシステム開発でのC言語の普及

 筆者がアセンブリ言語でプログラムを組んでいたころでも,C,FORTRAN,Pascalといった高級言語はすでに誕生していて,大型計算機やミニコン,ワークステーションなどで使われていました.また,CP/Mと呼ばれるマイコン用のOSで動作する高級言語も存在していましたが,

・実行速度が遅くなる
・ROMに入らなくなる

といった理由でほとんど使われていませんでした.その後,MS-DOSが全盛のころになると68000や8086といった16ビットCPUが使われるようになり,ROMの最大容量が64Kバイトから1Mバイトや16Mバイトに増え,CPUの速度も高速になったため,前述の欠点が致命的でなくなり,次第に高級言語が使われるようになりました.

 とくに,日本では異常なほどCコンパイラが流行しC言語が普及していきました.筆者もZ80のシステムを68000のシステムに移行した際にZ80のアセンブリ言語のプログラムを68000のC言語(一部はアセンブリ言語)のプログラムに書き換えてC言語を使うようになりました.

 一度,C言語で記述してしまえば,アセンブリ言語よりもプログラミング効率が良いため,その後の大幅な機能追加もかなり楽になりました.このころはC言語人気から,特殊なCPUや新しく開発されたCPUでも,C言語が利用できる状態になっていました.これが組み込み機器でC言語が使われる最大の理由です.今ではCコンパイラが存在しないCPUを探すほうが困難なほどに,いろいろなCPUに移植されています.

 最近,組み込み機器で多く使われるようになったRISC CPUは遅延分岐などのアセンブラプログラミングを難しくする要因があるため,C言語の使用が前提となっているといった事実もあります.

Cでプログラムを書くメリット

 Cコンパイラがあるからといっても,C言語で書かれたプログラムを別のCPUに移植するというのは68000→68020→68060といった上位のCPUに移植する場合を除けば,一般的にいわれているほど簡単ではありません.CPUの違い以前に,同じCPUでも,Cコンパイラをバージョンアップしたところ,生成コードが変わって動作しなくなったということも多々あります.同じCPUと同じコンパイラを長い間使っていると,知らないうちにそのCPUやそのコンパイラに特有のプログラミングを行っていることが多くなります.とくに,開発者が変わっていくと,初級者から上級者までのいろいろなレベルのプログラムが混ざっていって,移植性が悪くなっていきます.

 といっても,どのCPUであっても,慣れたC言語で記述できるというのは大きなメリットです.

 C言語は,

・構造化プログラミングに適している
・ポインタで特定のアドレスを直接アクセスできる
・参考文献が豊富なため,学習しやすい

といった利点もあります.構造化プログラミングは今では古いキーワードとなっていますが,可読性に優れたプログラムを記述できるため,組み込み分野では今でも現役です.

 ポインタはバグを生む大きな原因ともなるため,弊害もありますが,組み込み機器では特定のメモリやI/Oを直接アクセスしなければならないため,重要な機能です.

そこで今回の特集の読み方

 C言語の参考文献が豊富という点では,どれを読めばよいのか迷うという弊害もあります.しかし,大きな書店で実際に本を手にとって,自分のレベルに合ったものを探せば,わりと簡単に習得できると思います(インターネットで公開されている文献も少なくない).

 また,C言語は演算子の記号が特殊で,=と==,&と&&,|と||などのように間違いやすい演算子が少なくありません.これらの演算子は日常的な数学(算数?)の常識や他の言語と比較してかなり特殊なため,コーディングミスを誘発しやすくなっています.しかも,似ている記号が多いためにミスに気づきにくいといった面もあります.

 そこで,第1章では主としてANSI Cを対象として間違いやすいコーディング例を紹介しています〔組み込み分野ではいまだに使用されることがあるカーニハン&リッチー・レベルのCコンパイラ(以後K&R Cと呼ぶ)にも一部で触れている〕.これらの間違いやすいパターンを頭においておくことで,ミスを未然に防止するプログラミングを行うことができるようになるはずです.

 最近のコンパイラは警告やヒントとして記述ミスに該当しそうな個所をいろいろと指摘してくれるので,コンパイルエラーでないからといって,警告やヒントを無視しないように,できれば警告やヒントがでないように書き換える習慣をつけたほうが良いと思います(N先輩,A君登場).

 第2章ではコーディングの違いと最適化例として,同等の処理をポインタ風コーディングと配列風コーディングとで記述した場合,コンパイラの最適化がどのように違うのかを見ていきます.Cではポインタと配列はコーディング上は同じように記述できる場合があります.ポインタ風のコーディングのほうがCらしいことができるかもしれませんが,場合によっては,読みやすさの点で(とくに,2次元や,3次元などの多次元では)配列風のコーディングが良いこともあります.

 コーディングの違いによって,最適化がどのように影響を受けるのか,いくつか例をあげて見ていきます(N先輩,A君登場).

 第3章では関数作成の勘所として,関数の作成にあたっての指針を簡単に紹介していきます.Cのプログラムは関数が基本単位となっており,関数を寄せ集めて,一つのプログラムを構成していきます.役に立つ処理であれば,たとえわずか数行の短いプログラムであっても,独立した関数として記述しておけば,別のプログラムを作成するときにも利用可能となります.そこで,関数の作成にあたって自分なりの指針をもつようにすれば,プログラミングの上達が早くなるものと思います(N先輩,B君登場).

第4章ではデバッグの前準備の心得として,主としてデバッガを使わない一般的なデバッグ論について紹介していきます.デバッグというのはプログラム作成の最終段階です.しかし,デバッグ段階はまだまだプログラム作成の半ばあたりだと思ったほうが無難です.それだけに,デバッグを行うまでのプロセスや心構えも重要となってきます(N先輩,B君登場).

第5章では組み込みCプログラミングに関して紹介していきます.MS-DOS/Windows/LinuxなどのOS上のCプログラミングではスタートアップルーチンが標準で組み込まれているため,main関数から書き始めれば,プログラムは動作します.組み込み機器でも,こういったOSを使えば,その組み込み機器上でパソコンと同じようにソースをコンパイルして,実行し,デバッグしていくことが可能となります(N先輩,C君登場).

 組み込みCといっても,Cプログラミングですから,第1章〜第4章で紹介する例は組み込みCプログラミングの場合でも同じことです.しかし,組み込みCの対象となる組み込み機器ではキーボードや画面表示をもたないことがあり,その組み込み機器上でソースをコンパイルして実行するということができないため,パソコンやワークステーションなどでプログラムを作成し,コンパイルして実行ファイルを作成します.そして,それを組み込み機器上で実行しデバッグするといったクロス環境での開発が一般的です.

 OS上のプログラミングとクロス開発の最初の相違点はmain関数から書き始めたプログラムが組み込み機器で実行できないということです.

 じつはCプログラムのmain関数が実行されるまでにはメモリを初期化したり,割り込みベクタを設定したり,…といったスタートアップルーチンと呼ばれる影の下請けプログラムが実行されていて,そこから,main関数が呼び出されているのです.組み込み機器では,パラレル入出力や通信チップなどのハードウェアの初期化なども必要となり,その機器のハードウェアに合わせたスタートアップルーチンが必要となります.

 これが,OS上のプログラミングとの最初の相違点となります.初心者の間はスタートアップルーチンができている状態から始めることが多いため,何度か組み込み機器のプログラミングの経験がある人でも,スタートアップルーチンの存在を知らない人がいるかもしれません.しかし,小さな組み込み機器を一人で開発したり,大きな組み込み機器を取りまとめるようになるまでには,スタートアップルーチンを自力で書けるようになっておかなくてはいけません.そのスタートアップルーチンを記述するためには,たとえソフトウェア技術者であっても,ハードウェアの知識が必要となります.

 組み込み機器の場合は,ハードウェアを自作することのほうが多いため,ソフトウェアのデバッグ時に渡されるハードウェアは完全に動作しないことが多いため,自分のプログラムをデバッグする前に,ハードウェアの試験プログラムを作成して,ハードウェアの不具合個所をハードウェア設計者に指摘できる程度にはハードウェアを理解できるようにならないと一人前と呼べません.

 組み込み機器のプログラマを目指す方はわからなくても,自分のかかわっている組み込み機器のハードウェアの設計図を見せてもらって(できれば簡単にでも説明してもらって),ハードウェアに対する抵抗を徐々になくしていくようにしないといけません(筆者は就職したてのころ,「トランジスタ技術」の回路図がわからなかったが,毎月,眺めているうちにハードウェアに対する抵抗が少なくなり,回路図がそれなりに読めるようになっていった).

インデックス
◆プロローグ
第1章

今月号特集トップページへ戻る


Copyright 2004 中島 信行