第78回 プログラミングについて『いまさらですがC言語の門を叩こう その1』

だんだんとプログラミングの話が難しくなってきてしまいました。最近、プログラミングを始めたい方や、始めたばかりの方からのメールを頂くことが多くなりました。当初このコーナーを設けたときにはC言語のプログラミングをある程度は知っているくらいの層の方々を対象にしようと考えていました。『C言語の入門程度の知識は書籍を読んでもらえればいいだろう』ということで、その辺のことは殆ど触れていませんでした。ということで、しばらくの間はこれまでの話と重複する部分もかなりあるかも知れませんが、『いまさらですがC言語の門を叩こう』ということでお話しをしましょう。
コンピュータを触るようになってしばらくすると、だんだんと『もう少し簡単にできないかなあ』、『単純なことなんだけれどいつも同じことに時間がかかってしまう』などと不満が出てくるものです。家庭で趣味程度に触るのであればあまり切実に感じないかも知れませんが、これが仕事の中でのことならばそうはいかなくなってきます。そのようなときにフリーソフトを探す方もいるとは思いますが、必ずしも自分が欲しいソフトがあるとは限りません。たとえあったとしても使い勝手が良くないこともあります。例えばプログラムにしてしまえば10行程度の内容のものなどは、まずフリーソフトにはないはずです。結局のところは諦めてしまって不満を持ちながらコンピュータを使うか、『コンピュータなんて面倒臭いだけだ』と結論付けて物置に片づけてしまうなどということも少なくありません。
中には『プログラムが書けたらなあ....』とため息をつく方もいるはずです。ただその殆どの方は実際にプログラムを書いてみることもぜすに、ため息の山を築いてばかりいるのです。
前置きはこのくらいにして、本題に入っていきましょう。
コンピュータはソフトウェアがなければ何もすることができません。コンピュータの黎明期では、コンピュータのパネルに配線を行なってから実行させるなどということもありましたが(これも立派なソフトウェアには違いありませんが)、現在のコンピュータでは通常のデータと同じ様な扱いができるものになっています。
コンピュータが理解できるプログラムというのは機械語という0と1のデータの集まりしかありません。最もどんなデータファイルでも0と1の集合でコンピュータ上では扱われるのですが、ここで言うのは、
#include <stdio.h>
main()
{
printf("This is a pen.\n");
}
というC言語のソースプログラムを直接実行することができないということなのです。
このようなプログラムはあくまでも人間が理解しやすいように記述したものであって、コンピュータにしてみればこのプログラムを直接実行してくれなどということは、はなはだ迷惑なことなのです。
それでは、この人間が理解しやすいプログラムをコンピュータはどのように理解するのでしょうか。人間の世界でも同じことで、日本語しか分からない人に英語で話しても理解ができませんので通訳が間に入ることになります。このようにコンピュータの世界でもソースプログラムを通訳する人のことを、インタープリタとかコンパイラとか呼んでいます。もっともコンピュータの中に人間がいる訳ではなく、翻訳をするプログラムのことを言います。
コンピュータの世界では、人間が理解できるソースプログラムを最終的に機械語に翻訳するプログラムをコンパイラ、そうでないものをインタープリタと呼んでいます。ですので、パソコンのOSにまだDOSがなかった頃のBASICなどは、ソースプログラムを読みながら別の言語に置き換えて実行していましたのでインタープリタと呼ばれます。
ここではC言語のお話を中心にしますのでコンパイラについて考えてみましょう。コンパイラはソースプログラムを翻訳するプログラムですので人間の通訳と同じ様に、英語と日本語の通訳、中国語とスワヒリ語の通訳などどんな言語を通訳できるかが通訳をする人で違っています。そう、コンパイラも同じで、C言語のコンパイラ、FORTRANのコンパイラなど翻訳できる言語が決まっています。ただ違うところは、人間の通訳は2つの言語を双方向に翻訳できるのに対し、コンパイラは一方向しか翻訳することができません。
時々、ある言語のコンパイラはどんな言語でプログラミングしたのだろうと考えることがあります。ですが、コンパイラの言語をコンパイルした言語が何だろうなどと考えるときりがなくなってしまいますので、深く考えない方がいいと思います。
プログラミングを始めようと思い立ったとき(決心したときかな)に、まず考えなければならないのが、どのプログラミング言語でプログラムを書くかということです。ここではC言語を中心にお話しますのでC言語をお勧めしますが、好みの言語があるのであればそれでいいと思います。言語も決めたら次にどうしても必要なのがコンパイラです。自分の使っているコンピュータに既にコンパイラがあるのであれば、それを使えばいいし、ないのであれば購入しなければなりません。いざコンパイラを買おうと思って電気店に行っても安いものから高いものまであって、いったいどれを買ったらいいのか分からなくなりますが、安直な方法は自分のそばにプログラムを書く人がいるのであればその人の意見を聞くことです。意見を聞かずに同じものを購入してもいいかも知れません。私も、そばにいた人に聞いたら『OSがマイクロソフトだからマイクロソフトのものの方が相性がいいと思うよ』と言われてそれに従いました。
プログラミング言語の歴史を見てみると不思議なもので、国の機関などがこんな言語を作ろうといって新しい言語を作ったことはありません。もしあったとしても普及はせず、長生きできませんでした。たとえばADAというプログラミング言語はアメリカの国防総省が国防総省内のプログラミング言語の種類があまりにも多いのに困り果て、統一するために作ったものですが、この言語が世間一般に普及しているとは言えません。
では、新しいプログラミング言語がどのようにして誕生したかというと、志を持った個人や数人のグループが生み出してきたのです。高級言語の元祖であるFORTRANはジョン・バッカス・ナウアーというIBMにいたおじさんが、プログラムを書くのがもっと楽にならないか、誰もがプログラムを書けるようにならないかという志を抱いて作成したものでした。BASICもアメリカの大学の先生(だったと思いますが)2人が、誰でもが簡単にプログラムを作れるようにと作成しました。COBOLもアメリカのグレース・ホッパーおばさんが中心になって誕生したものです。
C言語も例外ではなく、アメリカのAT&Tのベル研究所のブライアン・カーニハンおじさんと、デニス・リッチーおじさんが作ったものです。その研究所にはBCPLというプログラミング言語があって、それをスッキリさせた言語をその頭文字をとってB言語というものを作りました(B言語の作者が誰だったかは記憶がありません)。そのB言語に改良を加えたのがこのおじさん達でした。このおじさんたちもいい加減なもので、B言語の次だからC言語という名前にしたのだそうです(BCPLの2番めの文字だという説もあります)。現在でもC言語の種類にANSIとかK&Rとか言う区別のK&Rはこのおじさんたちのイニシャルなのです。
しかしながら、C言語はそれだけでは多分普及しなかったはずです。C言語が普及したのにはもう1つの要素があったのです。UNIXというOSです。C言語が生まれた頃はコンピュータには現在のようなまともなOSがありませんでした。タイムシェアリングで、文字端末があり、同時に複数の人が使用できるなどという技術がまだ完成されてはいなかったのです。AT&Tは他の団体とMULTICSというOSの開発を共同でおこなっていました。このOSが現在のOSに近いものだったということでしたが、このプロジェクトは失敗に終わり中断されてしまったのです。カーニハンおじさんもその中の一人だったと思いますが、このOSができないと再びパンチカードとプリンタだけの世界に逆戻りしなければならなくなることに耐え切れず、AT&Tでこっそりと陰に隠れて自分達の欲しいOSを自分達で作り始めたのでした。とにかく、会社としては認められていないことをするのですから、使えるコンピュータや端末は廃品同然になっていたものを集めてきて、手に入らないものはワープロソフトを作るという名目で会社から資金を出させたのだそうです。
最初はアッセンブラという低級な言語で作成されたUNIXを、C言語で書き換えてみようということになりました。その当時、OSはアッセンブラで書くのだということが暗黙の了解のようになっていたので、かなりの冒険だったと思います。しかしながら、冒険は成功しました。C言語でOSが書けるというのが分かると、今度は違ったコンピュータにも移植してみようということになり、これも大成功だったのです。ところが、AT&Tはコンピュータ事業には手を出せないことになっていたため、このUNIXは大学に手数料とメディア料程度の金額(要するに只同然)でソースプログラムごと配布されたのです。
大学ではこれは使いやすいということで、UNIXが急速に普及しました。それに伴ってC言語でプログラミングする人も増え続け、これらの人たちが卒業とともに企業でUNIXを使うようになり、普及して当然のこととなりました。
ちょっと話しが脱線してしまいました。高級言語という言葉が出てきましたが、言語が高級というのは値段が高いとか安いとかで区別しているのではありません。一般にプログラミング言語は、
機械語
アッセンブラ言語
高級言語
の区別があり、機械語はコンピュータが直接理解できる言語で、コンピュータの種類(アーキテクチュア)に依存するもので人間が理解することは非常に困難です。アッセンブ
ラ言語も機械語と同様にコンピュータの種類に依存しますが、人間が理解できるようにコンピュータの命令がちゃんとした単語になっているものです。この2種類は低級言語(という言葉はあるのかな)です。それに対して高級言語というものは、基本的にはコンピュータの種類には依存しません。ですので、高級言語でかかれたプログラムはコンピュータに合ったコンパイラを使用すればどのコンピュータでも実行することができるのです。
通常、高級言語は次のようにして機械語に変換されます。
高級言語ソースプログラム
↓
コンパイラ
↓
中間言語
↓
リンカ
↓
機械語
C言語は他の高級言語と比較して小さい仕様の言語です。つまらないくらいに何も無い言語です。多分、言語そのものとしてはFORTRANを全部覚えるのに一ヶ月かかるとすれば、3日で全部覚えられる程度のものです。しかしながら、中身が少ないというだけで決して簡単であるとは言えません。かえって奥が深いかも知れません。FORTRANとC言語どちらの方が初心者には簡単ですかと問われると、FORTRANの方ですと私ならば答えると思います。慣れの問題なのですが、FORTRANの方がC言語よりも自然で、曖昧なところが少ないのです。
C言語の特徴を私の思うままに言うと、
・小さい仕様の言語
・構文がスッキリしている
・明快に表現できることがある
・文字列の扱いが面倒
・理解しづらいプログラムが書けてしまう
・ちょっと不自然
などが考えられます。なんだかあまり良くない言語のようですが、あまり気にしないで下さい。
C言語では、ソースプログラムのファイルの拡張子は .c です。またインクルード用のファイルの拡張子は .h が一般的です。なぜ .h なのかというと、インクルードするファイルは通常は定数の定義や関数の定義が記述されていてヘッダファイルと呼ばれているので、その頭文字をとって .h したのです。
それでは、一番小さいC言語のプログラムを作りましょう。
main(){}
これがC言語の一番小さい立派なプログラムです。C言語で書かれたプログラムには、1つだけ main という関数がなければなりません。この関数がないと、コンピュータはプログラムを実行するときに、どこが最初か分からないのです。ですので、C言語ではこの関数をメイン関数と呼びます。例えば、FORTRANではサブルーチンや関数ではないものがメイン関数と同様な扱いになります。
関数というのは、ある処理単位を1つにまとめたものと考えて下さい。上のプログラムも何もしない処理単位を1つにまとめた main という名前の関数ということになります。
プログラムの重要な要素の1つに、コメントがあります。コメントとは、プログラムの実行には何にも関係せず、ソースプログラムを理解しやすくするためなどに使用するものです。C言語ではコメントを /* と */ の間に記述します。ですので、
(1)
/* abcde */
(2)
/* abcde
*/
(3)
/*
abcde
*/
(4)
/*
abcde */
のどれもがコメントになります。コメントにするには / と * の間にスペースを開けてはいけません。コンパイラは連続した / と * のみをコメントの開始や終了と判断する
ようになっています。問題は次のようなときです。
/*
/* abcde */
*/
よくプログラムを作っていると、ある範囲をまとめてコメントにしてテストしてみたいときがあります。このようなときに、上のようにするとコンパイラによってはエラーとなることがあります。ここはC言語の曖昧なところで、コメントの入れ子を許しているコンパイラもそうでないものもありますので注意が必要です。出来る限りはコメントの入れ子は避けた方がいいと思います。
文字列の中に次の様になっていてもコメントにはなりません。
printf("/* abcde */\n");
しかし、
/*
printf("*/\n");
*/
となっているときはコンパイラによってはエラーになることがありますので、これも注意が必要です。
またコメントは実行文の途中にも記述することができます。
printf/* 表示 */("abcde\n");
このようにしたときは /* 表示 */ の部分はコメントと解釈されますが、このように書くとプログラムが分かり辛くなるので、
printf("abcde\n"); /* 表示 */
と書いた方がいいと思います。
それではまた次回。