データ型

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

データ型(データがた、data type)とは、(コンピュータにおける[1]データ)の種類に関する分類である。データタイプとも。具体的を見たほうがわかりやすいかもしれない。たとえば、1, 2, 0, -42 といったような値は整数型であり、"foo", "Hello" といったような値は文字列型である。データ型は、プログラミングなどにおいて、まずデータオブジェクト[2]などといったような値について、またさらに、それらに束縛される変数引数定数[3]など[4]、やリテラル、それらを組合せる演算子、さらにそれらからなるといったもののそれが議論される。

型の役割[ソースを編集]

いわゆる動的な言語の処理系では、実行時に、何らかの操作がその対象に対して正しいか否か、データ型にもとづいてチェックを入れたりする。型システム(静的[5])のある言語では、などの型に応じて、それに適用される命令がコンパイルされていくという基本的な役割のほか、型に応じてコンピュータで扱いやすいバイナリで記憶したり、関数、式が持つ型同士の整合性を検査することによって、プログラムの誤りを検出することや、(型にもとづいた範囲の)安全性の検証も可能である(「型理論」にもとづく。型システムの記事を参照)。

型の実装[ソースを編集]

C言語等では多くの場所に型を明示してプログラミングを行う。一方、OCaml等の型推論を持った言語では、型の明示は必ずしも[6]必要ではなく、処理系が自動的に式などの型を型推論により推論する。たとえば a = 1 + 2 という[7]があれば整数同士の加算結果だからaは整数といった具合に、文脈などから(すなわち、静的に)可能な限りで型を推論していくわけである。

一方、Perl等では変数は型を持たず、実行時に変数の指す先であるデータが持っている型の情報に従って、それが文字であれば文字に対応して、整数であれば整数に対応して、といったように動く。このように、一般に動的プログラミング言語といわれるような処理系では変数ではなくデータの方に型をもつ。

(動的か静的か、混在しているものもある。たとえばAWKでは、変数の内容は「数値か文字列か配列」になるのだが、「数値か文字列か」については動的、「配列かそうでないか」は静的である)

一般に動的プログラミング言語では型の特性に合わせた最適化(例えば常に浮動小数点レジスタを用いるなど)ができないので、実行速度という面では静的型に劣るなどと主張される。反面多態性や記述の容易さで動的型は融通が利き、Smalltalkなどのオブジェクト指向言語、スクリプト言語は「動的プログラミング言語っぽさ」が強い。

動的型と静的型のどちらが安全なプログラムを記述できるのかは長年論争の的であるが、双方とも適した問題領域、適した開発スタイルが存在し、異なった安全観念(アナロジー的になるため限界はあるが、アクティブセーフティパッシブセーフティの住み分けが参考になるかもしれない)を持つ点を理解しなければならない。

データ型の種類[ソースを編集]

単純型と複合型[ソースを編集]

Javaではprimitive types(プリミティブ型)とreference type(参照型)に二分されるため、いわゆるJavaグラマ脳的にはそのような2分法による分類が絶対のものと思われていることがあるようだが、その2種類に分類することが絶対なわけでもなければ、それぞれの内容についてもあらゆるプログラミング(言語)に共通というわけでもない。標準規格などといった言語仕様の詳細を追えば、同じ用語を使っていても、あるいは同じ名前の型やクラスでも、詳細に見れば、あるいはあきらかに内容が違うこともある。また言語仕様などというよりは実装(処理系)の側からの観点による分類もある。

とは言え、理論的な観点からはっきり言えることも無いわけでもない。たとえば「整数の配列」とか「浮動小数点数の行列」というような型は、整数あるいは浮動小数点数といった型から複合されて作られている「複合型」であると言える。それに対し、整数型などはそれとは違って部分を持たないような「単純型」と言える[8]。より詳しくは、代数的データ型のような考え方によってその型を定義した時に、定義中に他の型が現れるような型は「複合型」であり、定義中に他の型は現れないような型は「単純型」である、ということになる。(ここで、では「○△の配列」といったようにして、他の型と組み合わせることで型になるようなものは何なんだ、という疑問が出てくるかもしれないが、高度過ぎるのでここでは触れない)

他にも、いろいろな分類法が考えられる。

たとえば、ユーザ定義型といったようなものを定義できる言語の場合には、言語であらかじめ定義されている型とユーザにより定義される型という区別がある。ユーザにより定義できる型には制限があるかもしれない(たとえば、複合型しか定義できない、など)。一方で、言語の本体ではどんな型も定義されておらず、基本的な型も全て標準ライブラリ等と呼ばれる基本的なライブラリでユーザ定義型と同じ(考え方としては)ように、定義されているというスタイルのこともある。

第一級(first-class)か否か、という分類もある(詳細は第一級オブジェクトの記事を参照)。その型の値を変数の値とすることができ、その型の値を実引数として関数を適用でき、関数から関数適用の値としてその型の値を返すことができる、といったようなことが自由にできるのが第一級であり、そうでない型は第一級ではない。たとえばC言語では、引数として渡すと配列はポインタになってしまう、など色々と癖がある。また、function typeが第一級関数であれば、いろいろと高階の技法が使える。

また処理系の実装の側からの観点が強い分類だが、レジスタなどのワードに値が直接収まる型と、ワードにはポインタが入り、ポインタの先に実際の値がある型、といったような分類もある(実のところ、次で述べるJavaにおける分類は、これを言語のレベルに抽象化して持ち込んだもの、という印象が強い)。言語処理系実装の論文などで、前者についてimmediate(即値)という表現が見られるかもしれない(機械語における、命令の直後に引き続いたデータという意味のimmediate(即値)と、似ているが異なるものなので注意が必要)。ポインタ自身に型などといったような情報を含ませることもある(en:Tagged pointer)。

また、Javaでは、Javaにおけるクラスのインスタンスである(あらゆる)オブジェクトについて、その型は「参照型」であり、intなどそれ以外の限られた全ての型は「プリミティブ型」である。ユーザが定義できるのは、型を定義できるというよりも、クラスを定義できると表現するのが正確ではないかと思われる。

以下の列挙の基準等はよくわからないが、幾人かによる編集により、よくわからないものになったと思われる。敢えて除去することもないと思われるので、そのまま残す。

単純型の例[ソースを編集]

前述のように、ここの節の分け方は、幾人かのウィキペディア編集者による恣意的なもの以上のものではない。

  • 文字型/文字列型
    • 文字型 - C/C++などでは数値型の一種で、文字を文字として扱う特別な単純型はない。
    • 文字列型 - 特に文字列型を設けず、文字型の配列で文字列を表すプログラミング言語もある(例:C/C++)。逆に文字型を設けず、文字列型しかない言語もある(例:Visual Basic バージョン6まで)。
  • 数値型 - 精度とサイズ・処理速度のトレードオフがあるため、サイズと精度が異なる複数の型を持つ言語が多い。
    • 整数型 - 整数を扱う型。
      • 符号付き整数型 - 負整数も扱える。一般に整数型は符号付きだが、符号付き整数型と符号なし整数型を別に持つ言語もある。
      • 符号なし整数型 - 非負整数(0か正整数)のみを扱える。
    • 実数型 - 実数を扱う型だが、厳密に無理数超越数を正しく扱えるわけではない。(理由は下の各項目を参照のこと。)
  • ブーリアン型 - 論理型、ブール型とも。多くの言語では真偽2値のみを扱うが、3値論理を扱う言語もある。
  • 日付型 - 日付や時刻を扱う型。日付を扱う型と時刻を扱う型が別々の場合もある。
  • バイナリ型 - バイナリデータを扱う型。言語によってはバイナリ型を持たずに数値型の配列(例えばCでは1バイト整数型の配列)で表現する場合がある。固定長バイナリと可変長バイナリに分かれている言語もある。
  • 関数型 - 第一級関数を持つプログラミング言語では、関数を値として扱うことができる。
  • ポインタ型 - 参照型、ハンドル型、オブジェクト型などとも。ポインタ型と呼ぶ場合はポインタ演算の存在を期待されていることが多い。内部表現はアドレスを表す整数型であることが多い。
  • void型 - 関数の返り値や引数などで、対応する値が「ない」ことを示すための型。
  • ユニット型 - 関数の返り値や引数などで、対応する値が「ない」ことを示すための型。void型との違いは、void型の値(オブジェクト)が存在しないのに対し、ユニット型にはユニット型の値が存在することである。

配列型、関数型、ポインタ型はそれぞれ「~型の配列」、「…型を引数に取り~型を返す関数」、「~型へのポインタ」などと表現し、基にする型がしばしば存在する。そのためCC++ではこれらを一括りにして「~型の派生型」と分類している。

複合型の例[ソースを編集]

前述のように、ここの節の分け方は、幾人かのウィキペディア編集者による恣意的なもの以上のものではない。

  • 配列型 - ベクトル型とも。
  • リスト型 - 配列型に似るが、インデックス(番号)ではなくポインタ(前後のつながり)で管理されている。
  • タプル型 - ペア型とも。固定長の組からなる型。
  • 数値型
    • 複素数型 - 複素数を扱う型。実数型があれば複合型として実現できるが、言語によっては単純型として用意している。
    • 純虚数型 - 純虚数のみを扱う型。実部が不要な分、記憶域や計算に必要なコストを抑えられる。
    • 四元数型 - 四元数(クォターニオン)を扱う型。特に3次元コンピュータグラフィックスの処理で便利なため、言語によっては用意されていることがある。大抵のプログラミング言語ではライブラリにより複合型として実現される。
    • 有理数型 - 有理数を分母と分子の組として表現する型。
    • 多倍長整数型 - 任意の容量を使い、任意の桁数の整数を表す。これを浮動小数点数や有理数型の要素型に使って実数を表すことも多い。
    • 区間型
  • 行列型 - 配列型に似るが、行列演算ができる。スカラー型・ベクトル型・行列型を区別する言語と、スカラーやベクトルも列数や行数が1の行列として表す言語がある。

[ソースを編集]

  1. ^ 型理論などは論理学や数学などもっと広い範囲のある話だが、この記事ではもっぱらコンピュータ、特にそのプログラミング言語に関して説明する。
  2. ^ 「データオブジェクト」(data object)でまとまったフレーズである。「オブジェクト指向の意味でのオブジェクト」よりもっと広い。
  3. ^ 定数リテラルとは違う。詳細はそれぞれの記事を参照。
  4. ^ ここで「など」というのは、たとえば関数名も、関数オブジェクトないし関数という型(英語で function type(en:Function type)なのだが、functional の定訳である「関数型」と被るためうまく訳せない)の値を持つ定数(ないし変数)だったりする、ということであるが、そういった翻訳の事情もあり一言でうまく表現できない。
  5. ^ 理論的な文脈では、型システムといえば静的であるので、特に断らない場合があるため、ここではカッコに入れた
  6. ^ 理論上の限界だけでなく実装上の限界もあるので、必要な場合もある。
  7. ^ あるいは定義
  8. ^ なお、浮動小数点型は、仮数部と指数部から成る複合型、というような実装になっている言語も、もしかしたらあるかもしれない。

関連項目[ソースを編集]