コンピュータの基礎第9講
言語プロセッサー
【第9講のポイント】
本講では、プログラム(ソフトウェア)を書くときに用いる様々な高級言語の特徴とプログラミングの手順を学ぶ。さらに、プログラム言語で数式を扱えるようにするための基本的な原理を理解するとともに、それに必要な計算機科学の基礎概念を学ぶ。
【第9講の目標】学習後、以下のことが身についたかチェックしよう。
- 代表的な高級言語の名前と特徴を理解している
- プログラミングの手順を理解している
- コンパイラとインタプリタの違いを理解している
- スタックについて理解している
- 後置記法の計算法を理解している
- 中置記法の後置記法への変換法を理解している
【第9講の構成】
- 言語プロセッサー
- 数式の記法
- 後置記法式の計算
- 後置記法への変換
本書の見方
- ページをめくる
- 左(右)ページの左(右)端クリックまたはドラッグする
左(右)矢印キーを押す
- 1ページ分の移動
- 左右上端にある[Next]、[Previous]タブをクリックする
- 節の頭に移動
- 右上の【節の移動】タブをクリックし、現れた節を選ぶ
- ページのジャンプ
- 右上のページ番号表示タブをクリックし、現れたページを選ぶ
- 画像の拡大およびリンク先への移動
- 画像やリンク先をクリックすれば、別ウィンドウ(タブ)で表示される
第1節 言語プロセッサー
人間が理解しやすい高級言語で書かれたプログラムをコンピュータが実行可能な機械語に翻訳するソフトウェアは、プログラム全体を機械語(アセンブリ言語)に翻訳するコンパイラと、プログラムを1文ずつ翻訳しながら実行するインタプリタに分かれるが、その特徴を以下に述べる。
コンパイラ
実行時の速度は速い
プログラム(全体)を完成させないと実行できない
プログラムに対する規制が強い→誤りを見つけるのは容易
大規模プログラムやシステム開発に向く
コンパイラの作成は難しい
インタプリタ
実行時の速度は遅い
プログラムの一部でも試験(実行)できる
プログラムに対する規制が緩やか→誤りを見つけるのは困難
小規模なプログラムに向く
インタプリタの作成は容易
インタプリタがコンパイラに比べて実現が容易である理由は翻訳の際に、実行時の情報を利用できる点がある。例えば、変数に入る値の型が、計算の進行につれて変わる(実際に計算して初めて分かる)ようなこと(
動的型付け)をコンパイラで実現するのは難しい。
主な高級言語とその特徴
以下、主な高級言語とその特徴をあげる。他にも多くの高級言語があるが、それぞれ理念(プログラミングパラダイム)や目的に応じた特徴を備え、以前(他)の言語がもつ短所を克服しようとして発展してきた。
言語には大きく
手続き型言語と
非手続き型言語がある。
手続き型言語のプログラムは問題の解法手順(How)を記述し、その記述(命令)が順番に実行される。ほとんどのプログラム言語がこれに該当し、処理速度は速いが、動作の理解には計算の流れを順に追う必要がある。
一方、LISP(関数型言語)やPROLOG(論理型言語)などの
非手続き型言語のプログラムでは、問題自体(What)を(数学的な)関数あるいは論理式として定義し、その定義に基づき計算が進行する。
オブジェクト指向言語は、操作手順よりも操作対象に重点を置く手続き型言語で、対象と付随する操作をまとめたオブジェクトを生成し、互いにメッセージ(指示・依頼)を送り合うことにより処理を進めていく。
- FORTRAN(FORmula TRANslation、1957年)
科学技術計算用。IBMが開発した。豊富な計算ライブラリが蓄積されている。
- COBOL(COmmon Business Oriented Language、1060年)
事務処理用言語。米データシステムズ言語協議会が開発。プログラムの文書性が高く、英語に近い表現で記述可能。
- BASIC(Beginner's All-purpose Symbolic Instruction Code、1964年)
初心者用。大学での教育用に開発された。後にマイクロソフトによってパソコンに搭載され、同社およびパソコンの隆盛につながった。
- LOGO(LOGOs、1967年)
構成主義教育の理念に基づき、タートルグラフィックスを用いた児童の思考能力訓練を目的とする。
- SMALLTALK(1972年~)
LOGOにアラン・ケイの「メッセージング」概念を組み合わせた、最初の純粋オブジェクト指向言語およびそれによって記述構築された統合プログラミング環境。
- SCRATCH(2006年)
児童向けプログラミング(SMALLTALKの流れを汲むSQUEAK言語)学習環境。可能な限り簡単に学習できるように、触覚的なプロセスを通したプログラム構築とテストを可能にした。
- PASCAL(1970年)
教育用プログラミング言語。簡素で厳密な構造化を持つ言語で、教育用だけでなく実用的にも広く使われた。
- LISP(LISt Processing、1960年)
リスト処理を基本とする人工知能用言語。プログラムを数学的な関数定義として記述する関数型言語
- PROLOG(PROgrammation en LOGique、1972年)
人工知能用言語。プログラムを論理式で記述し、その自動証明を計算とみなす。
- C(1973年)
汎用言語。OSの記述にも使える言語として開発。
- C++(1983年)
Cにオブジェクト指向機能を加えた言語。
- JAVA(1995年)
プラットフォーム(実行機種)に依存しないソフト開発が可能なオブジェクト指向言語。携帯から大型コンピュータまで幅広く利用される。
- PYTHON(1991年)
汎用のインタプリタ言語。生産性と信頼性を重視してプログラムの可読性を高め、便利で大規模なライブラリを備える。
- JavaScript(1995年)
オブジェクト指向のインタプリタ言語。主なWebブラウザに実装されており、動的でインタラクティブなWebページの記述に利用される。
paiza.ioのページや
Coding Groundのページ等、様々な
プログラム言語実行サイトでこれらの言語を試すことができる。
プログラミングの手順
プログラムの作成から実行まで、例えばC言語では、次のような手順を経る。
- アルゴリズムの設計:問題を解く(計算する)手順を考え、必要ならフローチャートを描く
- コーディング:エディタを使ってソースプログラムを作成・編集する
- 前処理:プリプロセッサーがソースプログラムから前処理済みソースプログラムを生成する
- コンパイル:コンパイラが、前処理済みソースプログラムからオブジェクトプログラムを生成する。
ここで(文法的な)エラーが見つかれば、2.に戻る
- リンク:リンカが、オブジェクトプログラムにライブラリ(中の必要な)ファイルを結合して、実行プログラムを生成する。
- 実行:実行プログラムを実行する。
ここで(実行時)エラーが見つかれば、デバッガ等を利用して原因を突き止め、2.に戻る。
プログラム例:C
#include <stdio.h>
main(){
int x, y, wa;
x=10;
y=30;
wa=x+y;
printf("和= %d",wa);
}
#include <stdio.h>
プリプロセッサーが、標準入出力ヘッダーファイル(stdio.h)を取り込んで、ここに展開する。これにより、"printf(・)"関数が何であるかが(コンパイラ・リンカに)わかる。
printf("和= %d",wa);
リンカが、stdio.hの情報をもとに、標準入出力ライブラリ(関数の集まり)中のprinf関数とオブジェクトプログラムをリンクする。
この命令を実行する時点で変数waの値は40なので「和=40」と表示される。
paiza.ioのページでプログラムを入力して確認してみよう。
|
- ソースプログラム
- 前処理済みソースプログラム
- オブジェクトプログラム
- ライブラリ
- 実行プログラム
- エディタ
- プリプロセッサ
- コンパイラ
- リンカ
- デバッガ
|
第2節 アセンブリ言語での数式記述
言語プロセッサー(コンパイラ)が高級言語を機械語やアセンブリ言語に変換する仕組み(コンパイラの理論)を理解するのは難しい。この節では、簡単な数式をアセンブラで記述することを考えてみよう。
以下、簡単のために、汎用レジスタGRは1個だけとし、使える命令は、
- LD GR,n:メモリーn 番地の内容を汎用レジスタ(GR)にコピーする
- ST GR,n:汎用レジスタ(GR)の内容をメモリーn 番地にコピーする
- ADD GR,n:メモリーn 番地の内容を汎用レジスタ(GR)に加える
- SUB GR,n:メモリーn 番地の内容を汎用レジスタ(GR)から引く
- MUL GR,n:メモリーn 番地の内容を汎用レジスタ(GR)に掛ける
の5命令とする。また、変数 w,x,y,zには各々アドレス1200, 1201, 1202, 1203を割当て、必要なら1204番地以降を使用してよいものとする。
例.アセンブリプログラムを考える際には、式を日本語で表してみるとよい。例えば、z=x+y は「xに」「yを足して」「zに入れる」ことだから
LD GR 1201 「xに」
ADD GR 1202 「yを足して」
ST GR 1203 「zに入れる」
となる。
|
- z=(x-y)×w
- z=x+y×w
- z=x-y×w
|
第3節 数式の記法
最初の高級言語FORTRAN(FORmula TRANslation)が数式の記述を可能にしたことを述べた。以下の節では、その仕組み(アイディア)を簡単に解説する。
数式の通常の記法は演算対象(被演算子という)の間に演算記号(演算子)を置くので、中置記法と呼ばれる。中置記法では、演算の順序を定めるのに括弧が必要であり、演算子の間に優先順位を定めて括弧を一部省略することも行われる。例えば、10-2×3=10-(2×3)で、加減算より乗除算が優先される約束になっている。この例の場合は、左から順に計算(処理)してはいけないので、中置記法はコンピュータには不向きな記法である。
|
- 普通の電卓で計算すると答はいくつになるか
- 関数電卓モード(あれば)で計算すると答はいくつになるか
|
一方、関数表記では、例えば sin 60°や f(x,y) のように演算対象の前に演算子(関数)が置かれる。このような記法を
前置記法という。
これに対し、演算対象の直後に演算子を置く記法を
後置記法という。後置記法は、括弧が不要で左から順に処理するのに適しており、次の節で述べるように、コンピュータにとって扱いやすい記法である。
また、後置記法は次の例に見るように、日本語の語順と一致している。
例.40 32 2 / - (40から32を2で割って引く)
40 32 - 2 / (40から32を引いて2で割る)
|
- 2+3-5
- 2+(3-5)
- 10/(2+3)
- Z=2+3*Y
ヒント:計算手順を日本語で表現してみよ
|
第4節 後置記法式の計算法
後置記法式は、コンピュータ処理に適した記法であり、スタックと呼ばれるデータ格納の仕組みを利用する。スタックは計算機科学の様々な場所に現れる重要な基礎概念であり、その操作命令は情報処理技術者試験の
アセンブラ言語 CASLⅡにも入っている。
スタック
スタック(棚)とは、データが常に上に積まれ(push)、上から取り出される(pop)記憶装置(仕組み)である。 棚にお皿を積むことをイメージするとわかりやすい。 このとき、最初に積まれたデータは(その上に積まれたデータがずべて取り出されて)最後に取り出されることから
FILO(First In Last Out)と言われる。
計算アルゴリズム
計算過程
式 | 10 | 2 | 3 | * | - |
| | | | | |
ス | | | | | |
タ | | | 3 | | |
ッ | | 2 | 2 | 6 | |
ク | 10 | 10 | 10 | 10 | 4 |
後置記法式のスタックを使った計算法を以下に示す。
読み込んだ数(変数)・記号が
・
数(変数)なら、その値をスタックに積む
・
演算記号なら、
スタックから必要数の値を取出し
演算結果をスタックに積む
・
終りなら、スタック上に最終結果が残る
下のアプリで、後置記法式を記入して【計算】ボタンを押せば、計算過程が表示される。ただし、スタックは右方向が上に表示される。試してみよう。
|
(1)3 12 + 4 * 3 7 * -
式 | 3 | 12 | + | 4 | * | 3 | 7 | * | - |
| | | | | | | | | |
ス | | | | | | | | | |
タ | | | | | | | | | |
ッ | | | | | | | | | |
ク | | | | | | | | | |
(2)5 3 4 2 - - + 6 *
式 | 5 | 3 | 4 | 2 | - | - | + | 6 | * |
| | | | | | | | | |
ス | | | | | | | | | |
タ | | | | | | | | | |
ッ | | | | | | | | | |
ク | | | | | | | | | |
|
第5節 後置記法への変換
通常(中置記法)の数式を後置記法に変換する際もスタックを用いる。
変換アルゴリズム
入力:数字や変数と
+ - * / ( ) =を使った中置記法式 出力:後置記法式
読み込んだ数・変数・記号が
・
数(や変数)なら、そのまま出力する
・
演算記号なら、【順位:
= <
+ - <
* /】
優先順位が自分以上の演算記号をスタックから取出して出力した後
スタックに積む
・
( 記号なら、スタックに積む
・
)記号 なら、
( 記号までの演算記号をスタックから取出しては出力する
・
終りなら、スタック中の演算記号を順に取出しては出力する
(1)10 - 2 * 3
式 | 10 | - | 2 | * | 3 | 終 |
| | | | | | |
ス | | | | | | |
タ | | | | | | |
ッ | | | | * | * | |
ク | | - | - | - | - | |
出力 | 10 | | 2 | | 3 | * - |
(2)2 * ( 3 + 4 )
式 | 2 | * | ( | 3 | + | 4 | ) | 終 |
| | | | | | | | |
ス | | | | | | | | |
タ | | | | | + | + | | |
ッ | | | ( | ( | ( | ( | | |
ク | | * | * | * | * | * | * | |
出力 | 2 | | | 3 | | 4 | + | * |
下のアプリで、通常の数式(中置記法式)を記入して【変換】ボタンを押せば、変換過程が表示される。ただし、スタックは右方向が上に表示される。試してみよう。
|
(1)( 3 + 4 ) * 5
式 | ( | 3 | + | 4 | ) | * | 5 | 終 |
| | | | | | | | |
ス | | | | | | | | |
タ | | | | | | | | |
ッ | | | | | | | | |
ク | | | | | | | | |
出力 | | | | | | | | |
(2)Y = 5 - 3 * Z / W
式 | Y | = | 5 | - | 3 | * | Z | / | W | 終 |
| | | | | | | | | | |
ス | | | | | | | | | | |
タ | | | | | | | | | | |
ッ | | | | | | | | | | |
ク | | | | | | | | | | |
出力 | | | | | | | | | | |
|