<プログラミング特論 for 慶應義塾大学理工学研究科開放環境科学専攻 M1 in 2002>

lecture 7

(本稿は Ellis Horowitz, Fundamentals of programming languages によるところが多い)

再び型について

データ型(data type)とは、対象(object)とその上で許される演算の組み合わせである。 データ型そのものはいわば型紙であって実質的な存在ではない(プログラム言語でいえば、 データ型は基本的にはコンパイラが用いるものである。実行プログラムは、もう意識しないか (目的プログラムに反映されているため)せいぜい、実行時チェックのため参照するだけである)。 演算は実際には、その対象のインスタンス(instance)に対して施されるものであって、 新たなインスタンスを作成したり、廃棄したり、変更したり、するものである。

命令型言語には、通常、組み込みデータ型(built-in data types)がある。 言語がはじめから用意しているものである。整数型とか浮動小数点型といった ものであり、一般には、計算機のハードウェア実装に深く関わっている(すべての組み込みデータ型がそうだと 言っているわけではない)。そのため、実行速度は十分に考慮されているが、 (計算機のハードウェアの違いを超えた)汎用性に欠けるきらいがある。最近は MPU の defacto standard 化と これまでの試行錯誤や IEEE 等の標準化努力の結果、いくつかのパターンに分けられるようになってきている。

なお,この講義のように情報科学系の学生向けの講義ではあまり言及しない事実に「基本的なデータ型には しばしば10進数が用意されている」ということがある.ビジネスの世界では,100万円を日歩1厘の利子で借りた 時の一日の利息が 99.99 円では困ることもあるのである.

組み込みデータ型

過去の主な命令型言語の組み込みデータ型を記す

	FORTRAN IV	FORTRAN77	Algol60		Pascal		C
---------------------------------------------------------------------------------------
	INTEGER		INTEGER		integer		integer		int
	(INTEGER*32, INTEGER*2, LONG)					long
	REAL		REAL		real		real		float
	LOGICAL		LOGICAL		Boolean		Boolean		Boolean
			CHARACTER			char		char
	DOUBLE 		DOUBLE						double
	   PRECISION	   PRECISION
	COMPLEX		COMPLEX

上でも述べたように、こうした組み込みデータ型の問題点は、桁数、精度、指数の範囲、 オーバフローの取り扱い、桁落ちの取り扱い、符号の取り扱い等にハードウェア依存の部分があるため、 言語間の単純な書き換えでは同一の結果が得られないことがあるのみでなく、 同一言語であっても実行する計算機を変えると結果が変わるということもある。

多型(polymorphic)又はオーバローディング(overloading)

通常一つの演算子は対象とするデータのデータ型は一組に特定して定義される。 しかし、少なくとも数値演算に関してはこれは非常に不便なため(integer 同士の加算と real 同士の加算の 記号が異なるといった事態は受け入れられるものではない)。 命令型の言語の数値データのデータ型に関しては原則として一つの演算子が複数の型に対する演算を 表現するようになっている。これを多型(polymorphic)又はオーバローディング(overloading)という。 オブジェクト指向言語では、メソッド(サブルーチンと考えてよい)を多型とすることが許されているし、 Prolog では自動的にすべての述語(サブルーチンと考えてよい)が多型となっている。 Ada ではもっと自由に多型を用いることができる。

組み込みデータ型の間の数値演算の多型はたいていは単純で理解しやすい。 二つの演算子の型が同一であればその型で計算される(なお、演算結果が同じ型になるものと、 より有効桁の長い型になるものとがある)。両者の型が同一でないときには、 表現できる数値範囲が広い方に変換されて計算されると理解すればよいからである(下表参照)。 例外は、固定小数点型数やそれ類似の表現(byte 等)で、符号ビットの扱いが絡む場合や、 固定小数点型から浮動小数点型に変換する場合で、有効桁を少なくせざるを得ない場合である (64 ビット固定小数点数から 64 ビット浮動小数点数へと変換しようとすると有効桁が減少する)。

	+		integer		real		double		complex
----------------------------------------------------------------------------------------
	integer		integer		real		double 		complex
	real		real		real		double		complex
	double		double		double		double		complex
	complex		comples		complex		complex		complex

文字型(character)と文字列型(string)

文字や文字列の取り扱いは言語によって大きく異なっている。 ここでは述べる余裕がないので省略するが使用する時には言語仕様を 読む必要がある(山勘が働かない)。

ポインタ型(pointer)

ポインタ型は Fortran, Cobol, Algol 等では存在しなかった。 PL/I で導入され、Pascal や Ada で洗練された。 ポインタ型は非常に強力な機能(非常に複雑なしかし便利なデータ構造を構成することができる) であるが、同時に訳の分からないエラーや破壊的な結果を引き起こすエラーを埋め込む原因ともなりやすい。 この反省に立って、Java では参照型としてより制限された形でポインタ型の導入を図った。 なお、LISP のデータ構造はある意味でポインタの集まりであるが、「手で」ポインタを付け替えるような 無茶をしない限り破壊的な結果を引き起こすことはない。

ポインタ型の変数に許された演算は、代入、比較、dereferencing である。 但し、C においては、加減算や increment/decrement が許されている。 Pascal を例に取り上げてみる。

	type	nextnode = ↑node ;
		node = record
			number: integer;
			next:   nextnode
		       end ;
この型を持った変数の宣言は、例えば、次の様になる。
	var x, y:  nextnode;
この後、 new( x ) を実行したものとする。 この時、 x に関連して次の様な表記がある。

C はもともと,OS 等を効率よく作成するための高級言語として設計されただけあって,細かいところまで 操作できるようになっている.ポインタ型はその良い例であり,他の言語にない融通性を持っている. しかし,その表現はわかりやすいとはいえず,誤りの原因となり易い. いくつか例を挙げておく.