で、これからの後半の講義では、「計算機はどのようにして動くか」と いう基本的な仕掛けを、自分で実際にプログラムを動かすということを通して 学ぶことにしたい。
この講義では、 Pascal という言語を使う。この言語を使う理由はいくつかあ る。体系だっていて理解しやすいこと、広く使われている C 言語と同じよう ないわゆる「構造化言語」であること、(構造化については特に説明しないが、 要するに Pascal で基本を理解すれば、 C/C++ あるいは awk, perl, Java と いった良く使われている言語を使うのは容易だということである)、 C に比 べるとプログラミングミスを発見しやすいことなどがある。
が、もっとも大きな理由は、「現在の駒場の計算機システムでは、 Pascal 以 外の言語は我慢できないほど遅い」ということである。
program example1(input, output); var a, b, c : real; begin readln(a); readln(b); c := a + b; writeln(c); end.上のプログラムは、簡単なPascal プログラムである。今日は、このプログラ ムを動かしてみるということが目標である。まず、このプログラムはどういうも のかを説明しておく。
一行目は、「ここでプログラムが始まります」という宣言である。この宣言は、 program 名前(input,output); という形になっている。「名前」は、 アルファベットで始まり、アルファベットまたは数字が続く。その後のカッコ は「そうすることに決まっているからつけないといけない」ものである。
註:計算機言語には、「そうすることに決まっているからそうしないといけな い」という類の決まりが非常に多い。これは多くの場合、もともとその言語が 設計された時にはそうするべきもっともな理由があったのだろうけれども、そ のあとの計算機ソフトウェアの変化で必要がなくなってしまったためなどである。 もちろん、そうではなくて単に言語を設計した人の趣味、あるいはなにかの理 論に基づく主張で決まっていることもある。
次の var a,b,c: real は、このプログラムではこういう「変数」を使 いますという宣言である。変数とは、計算機のメモリ中にとられる数(整数ま たは実数)をしまうための場所で、プログラムの中では名前をつけて使うこと ができる。形式は var 名前, 名前 ... : 型; というふうになる。名前 はプログラムの名前と同じように、アルファベットで始まり、アルファベット または数字が続く。型は今日使うのは real (実数型)と integer (整数型) である。
整数型では、数を32桁の2進数(これを普通32ビットの数という)で表す。0か ら 01....1 (1が31個並ぶ)までは普通に正の数を表し、 10...0 から 11...1 までが負の数を表現する。ただし、 11...1 が -1, 11...10 が -2, 以下 10...0が - 2の31乗 を表す。
これは現在の計算機でもっとも普通に使われている、2の補数表示という方法 である。このやり方の利点は、足し算の時には正負を考えなくて済むことであ る。他のやりかたには符号つき絶対値表示や1の補数表示があるが、いずれも 足し算のための回路が少し複雑になる。割算では余りは切捨てられる。余りを 求めることもできる。
実数型では、数を符号、2進数11桁の指数、2進数52桁の仮数の3つの部分(あ わせて64ビット)で表す。10進数でいえばこれは1234という数を(+/-)1.234 X 10の3乗と表すようなものである。
その次の begin は、ここでは「変数(など)の宣言(宣言部)が終ってここ からプログラムがどう動くかの記述(実行部)が始まるということを意味する 区切りである。
次の readln(a); という文(実行部の、セミコロンで区切ったまとまりを「文」 という)は「キーボードから入力した数字を変数 a にしまう。その次では b にしまう。
その次の c := a + b; は、 変数 a と b の和を計算して c にしまう。
最後の writeln(c); は変数 c に入っている値を画面に表示する。 その後の end. は、これでプログラムがおしまいですという宣言である。
まず、このプログラムをmuleで作成し、例えば example1.pas といった名 前でセーブしてみよう。
ここで、いくつかの注意をしておく。
「人が読めるプログラムを計算機がいちいち読みながら実行する」ということ も可能であり、そういう風に使うのが普通である言語も多い(例えば BASIC, awk など)しかし、多くのシステムでは一旦コンパイルしたものを実行する。 これは単にその方が速いからである。
コンパイルは、シェルウインドウで
pc example1.pas -o example1と入れる(例によって最後にリターンする)。すると example1 という名前の 実行ファイルができる。
./example1と入れる。(実際に入れるのは、 pc で -o の後に指定した名前である。これ を別のものにしていれば、別の名前を入れる。また、 -o をつけないで pc example1.pas とだけしていれば、 a.out という名前の実行ファイルがで きる)。このあとリターンすると、キーボードから数字を入れるのを待ってい る状態になるので、数字をいれてはリターンするのを2回繰り返せばその2つの 和が表示されるはずである。
少しプログラムを修正して、もう少し芸のあるものにしてみよう。
program example1_1(input, output); var a, b, c: real; begin write('Type in number 1:'); readln(a); write('Type in number 2:'); readln(b); c := a +b; writeln('Sum is : ', c); end.もう少しいろいろやってみよう。
program example2(input, output); var a, b: real; begin write('Type in number 1:'); readln(a); write('Type in number 2:'); readln(b); writeln('a + b = ', a + b); writeln('a - b = ', a - b); writeln('a * b = ', a * b); writeln('a / b = ', a / b); end.実行例
Type in number 1:1.5 Type in number 2:2.5 a + b = 4.00000000000000e+00 a - b = -1.00000000000000e+00 a * b = 3.75000000000000e+00 a / b = 6.00000000000000e-01これは四則演算してみただけである。さらに少し変えて見よう。
program example2_2(input, output); var a, b: integer; begin write('Type in number 1:'); readln(a); write('Type in number 2:'); readln(b); writeln('a + b = ', a + b); writeln('a - b = ', a - b); writeln('a * b = ', a * b); writeln('a / b = ', a div b); end.実行例
Type in number 1:5 Type in number 2:2 a + b = 7 a - b = 3 a * b = 10 a / b = 2ここでは変数を整数型にしてみた。整数型の割算には div という演算 子を使う。なお、余りを求めるには mod という演算子が使える。
例3
program example2_3(input, output); var a, b: real; begin write('Type in number 1:'); readln(a); write('Type in number 2:'); readln(b); writeln('a + b = ', a + b:30); writeln('a - b = ', a - b:30); end.これは write文のところで変数ではなく式を書いている。そのあとの :30というのは、30文字分の場所を使って書けということになる。実数 型の場合はそれだけ正確な表示となる。整数型では単にそれだけのスペースを とるという意味しかない。これはきれいに行をそろえたい時に使う。
なお、もっと複雑な式やいくつかの数学関数も使える。たとえば
c := (a+b)*(a-b); c := sqrt(a*a+b*b); c := exp(a)+exp(-a);といったものを計算してみよう。
なお、PASCAL の文法の詳細や、どんな関数があるかといったことをすべてこの講義で説明することはできないので、必要に応じて参考書(第一回で紹介したもの、あるいは東大出版会からでている「情報処理入門」など)を見ること。