SIGMA-SE Math & Tech Library

SIGMA-SE Math & Tech Library


数学と情報技術をテーマに、書籍や教材だけではつかみにくい考え方を具体例とともに簡潔にわかりやすく伝える解説サイトです。
技術の歴史や背景、関連知識の整理、学習のための覚書や要約記事も掲載しています。

応用情報技術 - 基礎:7/21 プログラム構造と言語(制御構造・言語分類・記述言語)

概要

情報技術の基礎として理解しておきたい プログラム構造・言語 のうち、構造化プログラミング、言語の変遷、言語分類、マークアップ言語などを整理する。

途中状態を共有する呼出しや配置先が変わるアドレスの例で、プログラム構造の条件を確認する。手順と宣言、構文とデータの妥当性の違いも具体例で整理する。

この記事の構成

プログラム構造の種類

プログラムモジュールの性質は次のような観点で整理できる。

  • 再使用可能(リユーザブル)プログラム
    一度実行した後も必要な初期状態を整えることで、主記憶に置いた同じプログラムを再度正しく実行できるもの。
    このうち同時には一つのタスクだけが実行し、終了後に次のタスクが利用できるものを逐次再使用可能プログラムという。

  • 再入可能(リエントラント)プログラム
    実行コードを共有したまま複数のタスクから同時に呼び出しても正しく動作するプログラム。
    タスクごとに変わるデータを分離し、共有データを変更する場合は競合しないように設計する必要がある。

  • 再帰(リカーシブ)プログラム
    実行中に自分自身を呼び出すプログラム。呼出しごとの引数や局所変数などを区別して保持。
    再帰は自分自身を呼び出す処理構造、再入可能は複数の実行が重なっても安全という性質であり、同じ意味ではない。

  • 再配置可能(リロケータブル)プログラム
    主記憶上の特定の番地に固定せず、異なる開始アドレスへロードして実行できるプログラム。
    相対アドレスを使う方法のほか、ロード時にローダが再配置情報を基にアドレスを調整する方法もある。

  • 同じ処理をもう一度使えることと同時に使えることの違い
    共通の作業領域 temp に途中結果を置く関数を考える。呼出しAが temp = 10 を設定し、結果を使う前に呼出しBが temp = 20 を設定すると、Aも20を読んでしまう。Aが終わってからBを呼ぶ使い方では問題が見えなくても、処理が重なると結果が壊れる。

    リエントラントにするにはこのような途中状態を呼出しごとに分離するなど、再び実行が入っても干渉しない構造が必要になる。単にプログラム本体を書き換えないことだけでは、共有するデータの干渉を防げない。再帰呼出しも各呼出しの引数や途中状態を分けて保持する必要がある点でこの問題につながる。

  • 再配置では基準位置が変わっても参照先を保つ
    プログラム先頭から16 byte先にあるデータを参照する例を考える。先頭がアドレス1000なら参照先は1016、先頭が2000へ変われば2016になる。

    絶対アドレス1016を固定したままでは、別の場所へロードしたときに目的のデータを参照できない。基準からの相対位置を使ったりローダーが必要なアドレスを補正したりして、配置先に応じた参照を成立させる。再配置可能という性質はプログラムを繰り返し呼べるという性質とは別に考える。

プログラム言語の変遷

コンピュータのインターフェースは機械語(マシン語)と呼ばれ、プロセッサが実行可能な命令データで \(0\) と \(1\) の2進数で表現されるバイナリデータのことを指す。

この機械語と人間との橋渡しとしてアセンブリ言語や高水準言語が利用されてきた。
ただし、構造化やオブジェクト指向は言語を分類する観点の一つであり、古い分類を新しい分類が順番に置き換えたわけではない。複数の特徴を持つ言語も多い。

  • アセンブリ言語
    機械語の命令を人間が読みやすいニーモニックや記号で記述する低水準言語。多くの命令は機械語と密接に対応するが、疑似命令やマクロなど、必ずしも \(1\) 対 \(1\) にならない記述もある。

    加算演算が ADD、移動を MOV などで表現し \(2\) 進数より理解しやすい特徴がある。

    一方、命令セットやレジスタを意識して記述する必要があり、同じ処理でも命令数は対象のプロセッサや記述方法によって変わる。

  • 高級言語(高水準言語)
    機械語より人間が処理内容を記述・理解しやすいよう抽象化された言語。例えば\(A\) と \(B\) の和を \(C\) に代入する処理を「\(C = A + B\)」のように記述できる。

    代表例:COBOL、FORTRAN など。

  • 構造化プログラミング
    処理を基本3構造(順次、選択、繰返し)などの明確な制御構造で組み立て、無秩序な GOTO による分岐を避ける設計手法。特定の「構造化言語」だけに限定される考え方ではない。

    代表例:C言語、Pascal など。

  • オブジェクト指向言語
    データ(状態)とそれを扱う処理(振る舞い)をオブジェクトとしてまとめて設計する考え方を支援する言語。
    抽象化、カプセル化、継承、ポリモーフィズムなどが代表的な概念となる。オーバーロードやガベージコレクションは言語によって有無が異なり、オブジェクト指向そのものの必須条件ではない。

    代表例:Smalltalk、C++、C#、Java、オブジェクト指向COBOL など。

プログラム言語の種類

プログラム言語は処理をどのように表現するかという観点でも分類できる。複数のパラダイムを取り入れた言語もあるため、分類は排他的ではない。

  • 手続型言語
    手続きや関数を単位として状態を変化させる処理手順を記述する言語。

    代表例:COBOL、FORTRAN、C など。C++、C#、Java などは手続き型とオブジェクト指向の両方の特徴を持つ。

  • 関数型言語
    関数の適用を中心に処理を表し、データの不変性や高階関数を重視する言語。再帰がよく使われるが、再帰だけで定義される分類ではない。

    代表例:Lisp など。

  • 論理型言語
    述語論理を基礎として事実や規則と問い合わせを記述する言語。

    代表例:人工知能の研究開発で用いられる Prolog など。

  • スクリプト言語
    自動化やアプリケーションの制御、Web開発などで使われることの多い言語の総称。インタプリタで実行されることが多いが、実装によっては事前コンパイルやJITコンパイルも行われる。

    代表例:JavaScript、Perl、Ruby、PHP、Python など。JSP(JavaServer Pages)はJavaコードなどを埋め込めるサーバーサイドのページ技術であり、独立したプログラム言語ではない。

    スクリプト言語とインタプリタ方式は分類の観点が異なるため、同じ意味ではない。

  • 同じ集計でも手順を書くか結果の条件を書くかが違う
    「売上のうち100以上の値を合計する」処理を考える。手続き型では合計を0で初期化し、売上を順に読み、100以上なら合計へ足すという手順を記述できる。

    SQLなら SELECT SUM(amount) FROM sales WHERE amount >= 100; のように対象と集計内容を記述する。どの索引を使い、どの順番で読み出すかは通常DBMSが実行計画として決める。この違いが手順を中心に書くことと得たい結果を宣言することの違いである。実装方法の選択を処理系に任せる場合も、データや索引の設計が性能に影響する。

その他言語

プログラム言語以外にも、実行環境、通信手法、文書やデータの記述形式など、さまざまな仕様を用いる。

  • 共通言語基盤(CLI)
    CLI(Common Language Infrastructure)は実行可能コード、型、メタデータ、仮想実行システムなどを定めたECMA-335の標準仕様。.NETはCLIを基盤とする実装・技術群の一つとなる。

    複数の言語を共通の実行基盤で扱えるが、別のプラットフォームでそのまま動くかどうかはCLIの実装や利用するライブラリなどにも左右される。

  • Ajax(Asynchronous JavaScript + XML)
    Webブラウザ上での非同期通信により通信結果(レスポンス)をページ全体でなく部分的に書換える手法のこと。

    単一の部品や規格ではなく、JavaScriptとWeb APIを組み合わせる開発手法であり、交換データにはXMLだけでなくJSONなども使える。

  • データ定義言語(DDL:Data Definition Language)
    データベースの表や索引などの構造を定義・変更するSQLの命令群で、CREATE、ALTER、DROPなどが代表例となる。
    XMLのDTD(Document Type Definition)はXML文書の構造を宣言する仕組みであり、SQLのDDLとは別のものとなる。

  • マークアップ言語:HTML(HyperText Markup Language)
    Webページ作成(文書を保管・閲覧する)のために開発された言語でテキスト、音声、画像、動画、データファイルなどの表示やリンクを埋込むことができる。

    現在のHTMLはWHATWGのHTML Living Standardとして継続的に更新されている。WebSocketはブラウザから利用できる別のWeb API・通信プロトコルであり、HTML要素そのものではない。

  • マークアップ言語:XML(Extensible Markup Language)
    マークアップ言語SGMLを基に構造化された文書やデータを表現するために作られた言語で、文法には厳密なルールがある。

    文書構造の規則が必要な場合は、DTD(Document Type Definition)やXML Schemaなどで定義できる。

    XML文書はすべて整形式である必要があり、さらにDTDなどで宣言した規則にも適合する文書を妥当なXML文書という。

    • 整形式XML文書(well-formed XML Document)
      XMLの基本的な構文規則に従った文書。DTDなどの宣言は必須ではない。

    • 妥当なXML文書(valid XML Document)
      整形式であり、文書内で参照するDTDなどの構造規則にも適合した文書。

  • マークアップ言語:XHTML(Extensible HyperText Markup Language)
    HTMLをXMLの文法に従って定義したもので、要素を正しく入れ子にする、終了タグを省略しないなど、XMLの構文規則に従う。

  • スタイルシート言語:CSS(Cascading Style Sheets)
    文章やタグなどの要素をどう見せるかそのスタイルを定義するために作られた言語でHTMLやXHTMLで使用される。

    Webページでは文書の構造をHTML、見た目や配置などの体裁をCSSで記述し、役割を分けて管理できる。

  • JSON(JavaScript Object Notation)
    JavaScriptのオブジェクト記法を用いた軽量のデータ交換フォーマットのこと。

  • YAML(YAML Ain't Markup Language)
    配列やマッピングなどの構造化データを人が読み書きしやすいテキストで表現するデータシリアライズ形式。

    名前の由来は「YAMLはマークアップ言語でない」であり、マークアップ言語には分類されない。用途が重なる形式としてJSONがある。

  • 構文が正しいこととデータの意味が正しいことは別
    XMLの <user><age>abc</age></user> は開始タグと終了タグが対応しており、整形式のXMLとして扱える。しかし、年齢を整数とするアプリケーションの要件は満たさない。型や構造の制約をスキーマで定めたり読み取った側で検証したりする必要がある。

    一方、 <user><age>20</user></age> はタグの入れ子が交差しており、整形式ではない。データ交換ではまず文書を構文として読めるか、その後に項目や値が要件に合うかという二段階を区別する。

まとめ

  • プログラムの基本構造は順次、選択、繰返しとして整理できる。
  • HTMLは文書構造を表すマークアップ言語であり、XMLやJSONも処理手順ではなくデータを表現するために使われるが、記法と用途が異なる。
  • スクリプト言語は軽量な記述や自動化に使われることが多いが、実装によって事前コンパイルやJITコンパイルを行う場合もある。
  • 手続き型は処理手順を中心にし、オブジェクト指向はデータと操作をまとめて設計。
  • 再使用可能、再入可能、再帰、再配置可能は、それぞれ再利用、同時実行、自己呼出し、配置場所の変更に関する異なる性質を表す。
  • 繰返し使えることと呼出しが重なっても干渉しないことは別の性質になる。データ交換でも構文として読めることと業務の値として正しいことを分けて検証する。

参考文献

この記事を共有
Xで共有 Facebookで共有 LINEで共有



Copyright SIGMA-SE All Rights Reserved.
s-hama@sigma-se.jp