C言語の周辺事情
20170315 coskx
1.C言語の演習は何をやっているのか
・現在の演習では,terapadでCのプログラムを書いて,「ツールメニュー」から「コンパイル&ゴー」で書いたプログラムを実行している。そ もそもterapadはただのエディタ(editor)なので,文章やプログラムを書くことしかできない。演習をスムーズに行えるように,小坂がスクリプ ト(プログラムの一種)を書いていて,これが舞台裏で「コンパイル&ゴー」の命令を受け付けて,このスクリプトを実行している。エディタで書かれたプログ ラムのファイルはソースプログラム(source program),またはソースコード(source code)と呼ばれる。
・「コンパイル&ゴー」のスクリプト(script 簡易なプログラム)では,次の操作が行われる。
(1)コンパイラの環境を設定(パスや環境変数を設定)する。
(2)コンパイルパーサー(compile parser)である「cl.exe」を呼び出して,ソース・プログラム(xxxx.c)を実行形式のファイル(xxxx.exe)を作る。(cl.exeはコンパイラではなく,パーサ(parser)である。)
(3)実行形式のファイル(xxxx.exe)を起動している。
・コンパイル&ゴー+実行がうまくできた後には実行形式のファイル(xxxx.exe)ができているのを確認できているだろう。
・実行形式のファイルは機械語(machine instruction)で書かれていて,コンピュータにとっては理解できる命令が並んでいるファイルである。しかし,実行形式のファイルは0と1の 羅列であるため,人間がこれを理解するのは極めて難しい。人間は実行形式のファイルを16進法で表示して読むことが出来る。・コンパイルパーサー「cl.exe」は次の操作をしている。
(1)プリプロセッサ(preprosessor)
プリプロセッサがプリプロセス(preprosess)を実行し,#で始まる擬似的な命令にしたがって,ソースプログラム(xxxx.c)を修正する。ま たここでは「#include <stdio.h>」の記述があると,記述してあるところにファイル「stdio.h」を読み込んで展開する。
(2)コンパイラ(compiler)
コンパイラがコンパイル(compile)を行う。文法のチェックはここで行われ,エラーがある場合はエラーメッセージを表示して止まる。エラーがなければ,中間的なファイル(オブジェクトファイル(object file)などと呼ばれる)が作成される。
(3)リンカ(linker)
リンカがリンク(link)を行う。printfなどの関数をライブラリから取り寄せて,実行形式のファイル(xxxx.exe)に組み込む作業が行われる。
・なお,マイコンシステムでのプログラミングでは,ロケータ(locator)がメモリ配置を行なった実行形式のファイルを作成し,更に転送形式のファイルが生成される。
・C言語の入門編の授業では,小規模のプログラミングなので,いきなりterapadでプログラムを書いているが,プログラムが複数ファイルに分かれるなど 大規模なシステム開発の場合には,開発環境(例えばVisual Studio)が使用される。エディタももう少し頭が良くて,字下げが自動化されていたり,一行ずつ実行するデバッガでのデバッグが出来る様になってい る。(デバッガは初心者にとっては不親切である。)
2.C言語の他にはどのような言語があるのか
(1)アセンブリ言語
そもそもコンピュータは機械語(machine instruction)で 動作している。コンピュータが生まれたときは,機械語でプログラムするしか無かったが,機械語と一対一に対応するアセンブリ言語(assembly language)でプログラムを書くことが出来るようになった。人がアセンブリ言語で書いたソースプログラムは,アセンブラ(assembler)とい う翻訳プログラムによって,機械語へと翻訳(assemble)され,実行形式のファイル(executable file)となり,実行される。
技術の進歩に応じて,アセンブラはアセンブリ言語ファイルを翻訳し,中間ファイル(オブジェクトファイル(object file))を生成し,リンカがライブラリから取り出した必要なプログラムを合成して,機械語でできた実行形式ファイルを生成するようになっている。また,多くの疑似命令(アセンブラへ翻訳方法を支持する命令)を持つようになっている。
なお,機械語をアセンブリ言語に翻訳する作業をディスアッセンブリ(逆アッセンブリ disassembly)と呼び,その作業を行うプログラムのことをディスアセンブラ(逆アセンブラ disassembler)と呼ぶ。(動詞として使う場合はディスアセンブル(disassemble)する。)(2)高級言語
アセンブリ言語は機械語と一対一対応しているため,原始的な言語である。それに対して,アセンブリ言語以外の言語は人間にとって理解しやすいことから「高級言語」と呼ばれる。(2.1)命令型言語
人間にとってわかりやすさを備えた命令群を持つ言語として,
FORTRAN(1954, 1957) John W. Backus
ALGOL(1958)
BASIC(1964, 1970)
Pascal(1970) Niklaus Wirth
C(1972)
などが生まれた。しかし,FORTRAN,BASICなどではif文+goto文によってプログラムの実行予測が困難になることが指摘された。
ALGOL,Pascal,Cではgoto文を使わなくてもプログラミング出来るように改善された。(2.2)構造化言語(structured programming languages)
Goto文を使わないプログラミングは構造化プログラミングと呼ばれ,プログラマは構造化プログラミングを心がけるようになった。(プログラムのテキストの見た目の構造とプログラムの実行順序の構造の対応が付くようにする。)
特に関数(サブルーチン)やループ構造を記述する場合,Single-Entry Single-Exit(入口1つ,出口1つ)にすると可読性が高いプログラムとなるとされている。Goto文を使わないでプログラミングが出来る言語 (ALGOL,Pascal,Cなど)は構造化言語と呼ばれる。
技術の進歩に合わせて,FORTRANやBASICも含めて,殆どの言語は構造化言語になっている。
(2.3)オブジェクト指向言語(object-oriented programming languages)
ウィンドウシステム,グラフィックス,通信モジュールなど複雑な作業を行う時に,変数と手続きを一体化し抽象化の進んだオブジェクトを定義し,その実体 (インスタンス)を操作するプログラミングが使われるようになった。このようなプログラミングをオブジェクト指向プログラミングと呼び,そのような事のできる言語はオブジェクト指向言語と呼ぶ。
SmallTalk(1975)
C++(1985)
Python(1991)
JAVA(1995)
ObjectiveC
ObjectivePascal
C#(2000)
などがオブジェクト指向言語の例である。
3.実行の仕方によるプログラミング言語の分類
人間の書いたソースプログラムをどのように実行するかによってプログラミング言語を分類することがあった。
(1)インタプリタ言語
ソースプログラムを1行ずつ機械語に翻訳(インタプリット)しながらプログラムが実行される方式
初期の代表的な例はBASICインタプリタである
(2)コンパイラ言語
ソースプログラムはコンパイラによって,すべてが機械語に翻訳され,機械語プログラムが実行される方式
初期の代表的な例はFORTRANである。
(3)スクリプト言語
比較的単純なプログラムを簡易にプログラム出来る言語のことをスクリプト言語とよぶ。
インタプリタで実行される場合が多い。
UNIXシェルのシェルスクリプト,JavaScript,Perl,PHPなどがこのカテゴリに入ると言われている。
しかし技術の進歩とともに,インタプリタで動作するCや,中間言語に翻訳され,バーチャルマシン(機種依存のない仮想的なCPU)上で動作させるプログラムなどがあり,このような分類は余り意味がない。
4.広い意味でのコンピュータ言語
(1)状態モデルに基づくプログラミング言語
コンピュータで行うことの出来る作業として,コンピュータ内部(変数)の状態を変更するための複数の命令を,繰り返しや分岐を含めて順番に行うのが,これまでに述べたプログラミング言語(広い意味での命令形言語)である。
(2)関数モデルに基づくプログラミング言語
プログラムは関数の定義とその適用であるとして,プログラムを記述する言語がある。
Lisp (1958) John McCarthy
FP (1978)
Scheme
ML (1974)
Common Lisp
方程式の解法,数式の微分,積分などにLispが使われている。
(3)証明モデルに基づくプログラミング言語
計算とは、ある条件式を満足するものが存在することを証明することである。
プログラムとは条件を定義すること。
Prolog(1972)
三段論法で論理を証明する場面などで使われる。