8.

C++のデータ型一覧|整数・浮動小数点・char・boolの範囲と使い分け

編集
この記事の要点
  • C++の基本データ型は大きく分けて整数型intshortlonglong long)、浮動小数点型floatdoublelong double)、文字型charwchar_t)、論理型bool)の4系統。
  • 各型のサイズ(バイト数)や値の範囲は処理系(コンパイラ・OS・CPU)依存。規格は最小保証だけを定める。実際の値は sizeof<limits> で確認するのが確実。
  • 「環境が変わっても幅を固定したい」場合は <cstdint>int32_t など固定幅整数型を使う。
  • 整数は基本 int、小数は double を既定の選択肢に。型を間違えるとオーバーフローや精度落ちといった落とし穴がある。
  • 文字列(std::string)は別記事の領分。本記事では1文字を表す文字型までを扱う。

C++のデータ型のうち文字列以外(基本型)は、整数型・浮動小数点型・文字型・論理型の4系統に整理でき、それぞれサイズと表せる値の範囲が異なる。扱う値の大きさ・符号の有無・小数の要否に応じて適切な型を選ぶのが、正しく安全なプログラムの第一歩になる。

整数型 ― int / short / long / long long / unsigned

整数を扱う型。標準的な選択は int で、より大きい値や小さい値を扱いたいときに long 系や short を使う。型名の頭に unsigned を付けると符号なし(0以上)になり、負の値を捨てる代わりに正の最大値が約2倍に広がる。

  • shortshort int)… 小さい整数向け。最低16ビットを保証。
  • int … もっとも一般的な整数型。多くの環境で32ビット(4バイト)。
  • longlong int)… 最低32ビット。Windowsでは32ビット、多くのUnix系64ビットOSでは64ビットと、環境差が大きい代表例。
  • long long … 最低64ビットを保証。大きな整数が必要なら確実。
  • unsignedunsigned int のように付け、0以上のみを扱う。配列の添字やサイズ(std::size_t)などで登場する。

規格が定めるのは「shortintlonglong long」という大小関係と各型の最小ビット数だけで、実際のサイズは処理系に委ねられている点に注意。

#include <iostream>

int main() {

    int a = 100;         // 符号あり整数

    unsigned int b = 3000000000u; // 符号なし(大きい正の値)

    long long big = 9000000000LL;  // 64ビット級の大きな整数

    std::cout << a << \" \" << b << \" \" << big << std::endl;

    return 0;

}

浮動小数点型 ― float / double / long double

小数を扱う型。同じ小数でも精度(有効桁数)と表せる範囲が異なる。

  • float … 単精度。多くの環境で32ビット、有効桁はおよそ6~7桁。メモリ節約や大量データ向け。
  • double … 倍精度。多くの環境で64ビット、有効桁はおよそ15~16桁。C++で小数を扱うときの既定の選択肢
  • long doubledouble 以上の精度を持つ型。実際の幅は環境依存(80ビット・128ビット・doubleと同じなど、まちまち)。

浮動小数点数は2進数で小数を近似するため、0.1 のような値を正確に表現できないことがある。金額計算などで誤差が許されない場面では、整数(最小単位で持つ)や専用ライブラリの利用を検討する。

文字型 ― char / wchar_t

1文字を表す型。中身は文字コード(数値)であり、整数型の一種としても扱える。

  • char … 1バイト(規格上ちょうど1バイト=最低8ビット)。ASCIIなど1バイト文字や、バイト列の単位として使う。signed/unsigned どちらになるかは処理系依存。
  • wchar_t … ワイド文字型。幅は環境依存で、Windowsでは16ビット、多くのUnix系では32ビット。

C++11以降には char16_tchar32_t、C++20には UTF-8用の char8_t も追加されている。なお複数文字をまとめて扱う文字列は std::string で、これは別記事の領分。本記事では1文字単位の文字型までを扱う。

論理型 ― bool

真偽(true / false)を表す型。条件分岐やフラグに使う。整数へ変換すると true1false0 になり、逆に 0 以外の数値は true とみなされる。サイズは多くの環境で1バイト。

bool ok = true;

double pi = 3.14159;  // 小数は double が既定

char c = 'A';       // 1文字は char

if (ok) {

    // c は文字コード65としても扱える

}

各型の一覧(サイズ・範囲は代表値)

下表のサイズ・範囲は一般的な64ビット環境での代表値であり、規格上の保証ではない。実際の値は必ず sizeof<limits>std::numeric_limits)で確認すること。

分類 サイズ(目安) 値の範囲(代表値) 主な用途
short 整数 2バイト 約 -3.2万 ~ 3.2万 小さい整数・メモリ節約
int 整数 4バイト 約 -21億 ~ 21億 一般的な整数(既定)
long 整数 4 または 8バイト 環境依存(32/64ビット) やや大きい整数
long long 整数 8バイト 約 ±922京 大きな整数
unsigned int 整数(符号なし) 4バイト 0 ~ 約42億 0以上のみ・サイズ/添字
float 浮動小数点 4バイト 有効6~7桁 軽量な小数
double 浮動小数点 8バイト 有効15~16桁 小数(既定)
long double 浮動小数点 環境依存 double 以上 高精度な小数
char 文字 1バイト 1文字/バイト 1文字・バイト列
bool 論理 1バイト truefalse 真偽・フラグ

サイズは sizeof(int) のように書くとバイト数が得られ、範囲は std::numeric_limits<int>::max() などで取得できる。

#include <iostream>

#include <limits>

int main() {

    std::cout << \"int size: \" << sizeof(int) << \" byte\\n\";

    std::cout << \"int max:  \" << std::numeric_limits<int>::max() << \"\\n\";

    return 0;

}

型の選び方の指針

  • 整数は基本 int。それで足りないほど大きい値を扱うなら long long を選ぶ。
  • 小数は基本 double。速度やメモリが特に重要で精度を割り切れる場合だけ float を検討する。
  • 負の値を扱わないからといって安易に unsigned にしない。符号あり・符号なしの混在は意図しない巨大値への変換(後述)を招きやすい。
  • 幅を固定したい(ファイル形式・通信・ハードウェア制御など)なら <cstdint> の固定幅整数型を使う。
  • 真偽は bool0/1int で代用せず、意図を型で表す。
よくある落とし穴
  • オーバーフロー… 型の最大値を超えると値が破綻する。int の最大値(約21億)付近の計算では long long への昇格を忘れない。
  • 符号なしのアンダーフローunsigned0 から 1 を引くと負にならず、巨大な正の値(最大値付近)に化ける。ループ条件などで無限ループの原因になりがち。
  • 整数同士の除算5 / 22.5 ではなく 2。小数が欲しいなら 5.0 / 2 のように一方を浮動小数点にする。
  • 浮動小数点の等値比較0.1 + 0.2 == 0.3 は誤差で false になり得る。差の絶対値が十分小さいかで判定する。
  • サイズの決め打ち… 「int は4バイト」「long は8バイト」と決めつけない。環境依存であることを常に意識する。

auto と固定幅整数(<cstdint>)

C++11以降では、初期化子から型を推論させる auto が使える。型名を書く手間を省けるが、何型に推論されるかを意識しておくことは大切(例: auto x = 5;intauto y = 5.0;double)。

また、環境によらずビット幅を固定したい場合は <cstdint> をインクルードして固定幅整数型を使う。代表的なものに、ちょうど指定ビットの int8_t / int16_t / int32_t / int64_t(および符号なしの uint*_t)がある。

#include <cstdint>

int32_t v32 = 100000;   // 必ず32ビット符号あり

uint8_t b = 255;      // 0~255 の符号なし8ビット

auto n = 42;         // 推論で int になる

よくある質問

Q. int はいつも4バイト(32ビット)と考えてよいですか?
A. 多くの環境では4バイトですが、それは保証ではありません。規格は int に最低16ビットしか求めておらず、サイズは処理系依存です。確実に幅を固定したいなら <cstdint>int32_t を使い、現環境の値を知りたいなら sizeof(int) で確認してください。

Q. 小数を使うとき floatdouble のどちらを選べばよいですか?
A. 迷ったら double です。有効桁が15~16桁あり精度に余裕があるうえ、C++のリテラル(例: 3.14)も既定で double 型です。メモリや速度がよほど重要で、6~7桁の精度で足りると分かっている場合だけ float を検討します。

Q. 文字列を扱う型はこの中にありますか?
A. 本記事の文字型(char / wchar_t)はあくまで1文字単位です。複数文字をまとめた文字列は std::string という別の型で扱い、これは別記事の領分です。

まとめ

C++の基本データ型は、整数(int 系)・浮動小数点(double 系)・文字(char 系)・論理(bool)の4系統に整理できる。サイズや範囲は環境依存であることを前提に、整数は int、小数は double を既定とし、幅を固定したい場面では <cstdint> の固定幅整数を使う。オーバーフローや符号なしの挙動、浮動小数点の誤差といった落とし穴を押さえれば、用途に合った型選びができる。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. コメントアウト
  2. 文字列の結合/連結
  3. 変数の宣言
  4. 定数の宣言
  5. if文
  6. if文の論理演算子
  7. for文
  8. データ型(文字列以外)
  9. データ型(文字列)
  10. 配列とfor文
  11. 配列の要素数
  12. 多次元配列とfor文
  13. 多次元配列の要素数
  14. 関数の定義と呼び出し

最近更新/作成されたページ