=== 3. 型 ===========================

型とは

型は、データ型またはタイプとも呼ばれ、値の意味を定めるもの。
C言語には初めから備わっている基本型(プリミティブ型)と派生型がある。
たとえば、2つの変数 a + b という式があったとすると、両方ともint型なら整数の加算が行われるし、どちらかが浮動小数点数型なら適切な型変換が行われた上で加算される。さらに、変数aがポインタでbが整数ならば、ポインタを先に進めるという演算が行われる。

型の分類

C言語では、それぞれの型が具体的に何byte、何bit幅になるかの規定はゆるやかにしか行われていない。それぞれの型の詳細についてはコンパイラに依存することになる(処理系依存)標準ヘッダ<limits.h>には、個々の型の最小値と最大値が定義されているので、そこのシンボルを使うと移植性の高いプログラムを書くことができる。

プリミティブ(基本)型

C言語で初めから定義されている型。主に使うのは以下の4つ。
整数型(Integer Types)

  • char
  • int

浮動小数点型(Floating-point Types)

  • double

void型(値を持たない型。変数には使えないが、関数の戻り値やポインタで使用される)

  • void

派生型

プログラマが自由に定義することのできる型

  • 配列
  • 関数
  • ポインタ
  • 構造体
  • 共用体

関数型は「ある型の引数を受け取り、ある型の値を返す」という意味で派生型。なので、関数ポインタという概念が許されてる。

整数型

整数

intは整数を表す型。intは、そのコンパイラが対象としている機械で最も取り扱いやすい長さの整数を表す。
int, long int, short intは、全て符号付きです。符号なしにするには、それぞれにunsignedキーワードを付与します。

文字型(char)

文字型とは、キーボードから入力した文字やディスプレイに表示する文字、プリンタに印字する文字を表現する時に用いる型です。charは、C言語では整数型の一種です。なので、整数に対する演算は文字型に対しても行うことができます。

文字

文字定数は、'A'のように文字をシングルクォートでくくる。改行は'\n'、 改ページは'\f'。
文字列は、文字を並べたもの。文字の配列で表されて、'\0'(ヌル文字)で終端する。

有名な落とし穴

getcharはintで受け取ることになっている。それは、値がasciiに対応した文字の時とファイルの終端でEOFの時があるから。EOFは通常-1として扱われていて、char型が意味するものはC言語の規格上、signed charなのかunsigned charなのかは実装依存となっている。そのため、-1が255などの別の値に変換されてしまい、判定できなくなる。これは、isalpha()とかisalnum()などでも同じ

void型

C言語の型は通常は「何かを表現するため」にある。しかし、void型は「どれでもないものを表現するため」にある一風変わった型です。void型は値を持たず、演算もできない。
void型は、次の時に使われる

  • 関数の戻り値や引数として、値を返さないことや値を受け付けないことを示す
  • void *は汎用ポインタ型として使われる

void型の変数を宣言することはできませんが、変数をvoid型にキャスト(型変換)することはできます。voidは値を持たないので、その変数の値は破棄されます。(未使用の変数があって怒られた時に使える)

ポインタ型

ポインタ型とは、ある型のオブジェクトを指す型のこと。
ポインタ型の演算には以下のようなものがある

  • アドレス演算子(&a):変数aのアドレス
  • 間接参照演算子(*a):ポインタaの指す値
  • 代入(=)
  • 整数の加減算(+, -)
  • その他、比較など(==, <, >, …)

配列

配列は、ある型のオブジェクトを連続的に並べた型。C言語では任意の型の配列を定義することができる。配列の大きさはコンパイル時に定まっていなければいけない。配列の次元数は任意。

構造体型

構造体型とは、複数の異なる型を1つにまとめたもので、プログラマが定義する派生型の一種です。

型の大きさ(sizeof)

sizeof演算子を用いると、ある型の変数がメモリ上に占める領域の大きさを得ることができる。C言語ではある型が何バイトを占有するかは規格ではゆるやかにしか定められていないので、メモリ管理のプログラムなど、ある型のバイト数を特定しなくてはいけないプログラムを書くときはsizeof演算子が必須。

キャスト(型変換)

プログラムの時刻途中で、値の型が変化することがある。これを型変換と呼ぶ。

  • キャスト演算子による強制型変換
  • 通常の算術変換
  • 代入時の型変換
  • 関数呼び出しでの型変換

がある。