プログラム言語の種類と特徴

プログラム言語の変遷と分類

ハードウェアの発展とともに,より簡単にプログラミングをする方法が考えられてきました.最初は,処理を0と1で表現する機械語を使っていましたが,その個々の命令を記号化したアセンブラ言語が開発されました.さらに,色々な言語の開発により,日常語の表現に近い高水準言語によるプログラミングへ発展しました.

機械語とアセンブラ言語は,機械には理解しやすいですが,人間には理解しにくいので,低水準言語と言います.

高水準言語は手続き型言語(手続き向き言語)非手続き型言語(非手続き向き言語)に分かれます.前者は,処理の順序を流れ図に従ってプログラミングしますが,後者は,プログラムに何をさせるか簡潔に記述するだけで,処理手順を細かく意識する必要はありません.

コンピュータの発展段階を世代で表すのと同様に,プログラム言語の発展段階は,機械語が第1世代,アセンブラ言語が第2世代,高水準言語が第3世代,その次が第4世代言語(4GL)です.第4世代言語はソフトウェア開発の生産性向上を目標としており,定型的な業務処理に対し,簡単なパラメータの指定でプログラムを生成する機能をもちます.

また,パソコンやワークステーションが普及するにつれ,コンピュータに関する特別な知識を必要としないエンドユーザー言語が開発され,プログラミングの方法も多様化しました.表計算やデータベース等を扱い,今までの言語とは使用形態が違うので,EUCツールとも言われます.

さらに,特殊問題向き言語はソフトウェアパッケージの意味合いが強く,特定分野の応用ソフトウェアの作成を目的とします.

プログラミング言語の分類

Column

一連の処理基準を記述したものをスクリプトと言います.専門家の支援を得ることなく,利用部門が自分でプログラムを作成し,コンピュータを使って仕事を処理するための言語もスクリプト言語です.ワープロや表計算ソフトのマクロが該当し,EUCを支えるものとして注目されています.

スクリプト言語は,利用者の入力を待ち,入力があれば直ちに処理を開始するイベント稼働型です.

手続型言語

言語の名前 特徴
Fortran 科学技術計算用のプログラム言語で,通常の計算式がほぼそのままプログラムに使えます.現在では,構造化プログラミングに対応しています.発表当初,あまりの画期的な発明として自動プログラミングという言葉さえ使われたそうです.
ALGOL 普通の数学記法に近く,簡潔で厳密な文法等,アルゴリズムを表現しやすい仕様です.後に開発されたPL/I・Pascalに影響を与えました.
COBOL 事務処理用のプログラム言語です.英語に近い表現で記述でき,ファイルの入出力機能が充実しています.
PL/I 事務計算や科学技術計算等,色々なデータ処理分野に適用できます.ALGOLCOBOL・Fortran等の言語の特徴を取り入れた,非常に大きな言語仕様です.
Pascal 当初からパソコン用の言語として使われ,構造化プログラミングに適した命令があります.JIS規格になっています.
RPG 報告書作成用の言語で,所定の用紙にパラメータを記述する方法でプログラムを作成します.処理に応じて,プログラム指示書・入力ファイル指示書・出力指示書・処理指示書等が用意されています.流れ図の作成の必要がなく,プログラムの生産性を上げられます.
BASIC TSSの会話型プログラム言語として使われました.命令が短くて使用しやすいので,パソコンの入門者用の言語です.また,インタプリタ型の代表的な言語です.
LISP リスト処理用の言語です(「データ構造」の「リスト」を参照).データやプログラムをリストで表現し,関数を多く利用する言語で,人工知能用ソフトウェア開発言語として使われています.
APL 計算処理の手順を簡潔に表現するために考案された言語です.文法規則が少なく,特殊な記号で記述するため,他の言語より短い記述でプログラムを作成できます.
C UNIXを開発するために設計されたプログラム言語です.もともとシステム記述用として開発され,アセンブラ言語に近い処理が可能ですが,現在ではパソコンでも使われています.

論理型言語

言語の名前 特徴
Prolog 推論機能をもつ人工知能用ソフトウェア開発言語として使われています.

オブジェクト指向言語

言語の名前 特徴
Smalltalk オブジェクト指向プログラミングのための言語です.
C++ Cをオブジェクト指向型言語に改良したもので.Cの機能はほぼそのまま使えます.データとその処理手続きを1つにまとめたクラスが追加されました.
Java C++をベースとしたオブジェクト指向の言語ですが,ポインタ等の機能を外してシンプルにしています.多重継承は実装していません.Javaを実行するソフトウェア等(Java仮想マシン)を用意できれば,どのコンピュータでも実行できます.インターネットからアプリケーションをダウンロードし,ブラウザ上で実行させることもできます.インターネット上で動作するJavaアプリケーションをJavaアプレットと言います.さらに,Java言語を使って,サーバで動的にウェブページを生成し,クライアントに送信する技術をJSPと言います.

スクリプト言語

言語の名前 特徴
Perl テキストの検索や抽出,レポート作成に向いたインタプリタ型の言語です.CGIの開発に使われます.
PHP 動的にウェブページを生成するウェブサーバの拡張機能の1つであり,そこで使われるスクリプト言語です.XHTMLファイル内に処理を記述したスクリプトを埋め込み,結果に応じて動的に文書を生成して送出できます.また,XMLのサポートや各種データベースとの連携に優れています.言語仕様やプログラムはオープンソースです.
Python 文法の仕様等を最低限に抑える代わりに,利便性の高い大規模な標準ライブラリを備えています.言語仕様はオープンソースで,多くのプラットフォームで動作します.プログラムの文書化が重視され,適切なインデンテーションを行う必要があります.
Ruby インタプリタで実行する高機能なスクリプト言語であり,オブジェクト指向機能をもちます.位置づけがPythonと似ていますが,開発者は日本人です.

Column

近年は新しいプログラム言語が色々と作られ,数年ほどで普及することが多くなっています.ソフトウェア開発キット(SDK)が市販されたり,インターネット上で無料配布されることもあります.

また,プログラミングを容易に行うため,統合開発環境(IDE)を提供している言語も多いです.テキストボックス等のオブジェクト部品を,図形として配置すれば画面が設計できるものもあり,この機能をビジュアルプログラミングと言います.

プログラム言語の制御構造

C++言語を使って例を示します.

int plus(int m, int n) { int i; i = m + n; m = 8; n = 3; return i; } int main(void) { int m, n; m = 3; n = 5; printf(" m+n = %d\n ", plus(m,n) ); return 0; }

mainがメインルーチン,plusがサブルーチンです.plusはmとnの値を受け取り,その和(i)を戻り値とします.mainでは3と5の和を表示します.

mainでplus(m,n)としてサブルーチンを呼びだしており,このmとnは実引数です.一方,plusの中にあるmとnは仮引数です.実引数と仮引数の名前は重複しても構いません.

また,この例では,plus(m,n)を実行するときは,3と5という値そのものが渡されます(値呼びだし).plusでiにmとnの合計を格納し,その後にmとnに代入をしていますが,メインルーチンのmとnの値は変わりません(無意味な処理です).

次の例を示します.

void swap(int &m, int &n) { int temp; temp = m; m = n; n = temp; } int main(void) { int m, n; m = 3; n = 5; swap(m,n); printf(" m = %d n = %d\n ", m ,n ); return 0; }

mainがメインルーチン,swapがサブルーチンです.このプログラムを実行すると,mとnの値が交換されて,m=5,n=3となります.swapにはmとnの値そのものを渡すのではなく,mとnの変数が存在するアドレスを渡しています(参照呼びだし).仮引数と実引数のアドレスは違うため,値呼びだしでswapを実行しても,mとnの値は交換できません.

プログラム言語の記憶域

変数の種類とスコープ

void display(void) { auto int m = 8; static int n = 8; m = m * 2; n = n * 2; printf(" m = %d n = %d\n ", m ,n ); } int main(void) { display(); display(); return 0; }

mainがメインルーチン,displayがサブルーチンです.メインルーチンではdisplayを2回呼びだしています.displayで宣言されている変数の内,mは動的変数(呼びだされるごとに初期化される),nは静的変数(最初に呼びだされたときだけ初期化する)です.

最初にdisplayを呼びだした場合,mもnも2倍されるので,m=n=16となります.しかし,2回目の呼びだしでは,mが再び8に初期化されますが,nはそのままなので,それぞれ2倍すると,m=16,n=32になります.

次の例を示します.

int n = 8; void func(void) { int m = 8; } int main(void) { int m = 3; func(); printf(" m = %d n = %d\n ", m ,n ); return 0; }

変数nは大域変数で,プログラムのどの部分でも値を参照・変更できます.一方,funcで宣言された変数mは局所変数で,その変数の有効範囲(スコープ)はfuncの中だけです.funcの処理が終わると,変数mの内容は無効になり,mainで呼びだしても値は変わりません.

よって,表示される値はmが3,nが8となります.

プログラムの実行と記憶領域

プログラムが実行されると,メモリ上にスタック領域ヒープ領域が確保されます.プログラム実行のための一時的領域ですが,ヒープ領域はプログラム側から任意の順番で確保・解放の要求ができるため,一般的にスタック領域よりも多くの処理が必要です.

プログラムから動的な確保や解放を繰り返すと,ヒープ上に小さな未使用領域の断片(ガーベジ)が多く発生します.ヒープ全体の空き領域は足りていても,断片だらけの場合,断片より大きな領域を確保することができません(メモリリークが発生します).断片を集めて大きな未使用領域に再編成(ガーベジコレクション)することで,メモリリークの発生を防げます.