size_t型
概要
vector や string 型などの添え字やデータサイズを扱うときに使う整数型。
.size() を取得するたびに int 型変数へ代入してから使うなら、知らなくても問題ない。
size_t 型は符号なしの整数型。
何ビットであるかは環境によるが、AtCoder環境では $64$ ビット。
現代なら、ほとんどの環境で $64$ ビットであると思われる。
$64$ ビットの場合、扱える値の範囲は $0$ から $18{,}446{,}744{,}073{,}709{,}551{,}615$ まで。
これより大きいサイズのデータを扱うことはないので、上限超えは心配しなくてよい。
むしろ、意図せず $0$ より小さい数を扱ってしまう不具合が出やすいので注意。
宣言と初期化
宣言だけする場合
size_t a;
初期化もする場合
size_t a = 0; // 固定値で初期化
size_t b = a; // 他の整数型や double 型の変数で初期化
可能な演算
size_t 型では、int 型とほぼ同じ演算ができる。
詳しくは「int型」の記事参照。
ただし、符号なし整数型なので、小さい方から大きい方を引くと正しい結果にならない点に注意。
よく使う処理
vector や string 型の中身を全てループ
大きさが変数で与えられていない場合、ループを普通に書くと、以下のようにしたくなる。
for (int i=0; i<vec.size(); i++)
ところが、.size() の返り値は size_t 型なので、
int 型と size_t 型の比較を行っているという警告が出る。
for (size_t i=0; i<vec.size(); i++)
と書くことで警告を防ぐことができる。
もっとも、警告が出ても無視してよい場合もあるし、
ループ前に .size() の値を int 型変数へ入れて使用してもよい。
C++20以降であれば、ssize() 関数を利用して、以下のように書いて size_t 型を避けてもよい。
for (int i=0; i<ssize(vec); i++)
注意点
$18{,}446{,}744{,}073{,}709{,}551{,}615$ 番目へのアクセスが発生した場合
vector や string 型の中の要素へアクセスするとき、
添え字 i は size_t 型として扱われる。
想定外の挙動によって i が -1 だった場合、
size_t 型へ変換されたときに
$18{,}446{,}744{,}073{,}709{,}551{,}615$ として扱われる。
配列の範囲外アクセスのエラーメッセージで、
$18{,}446{,}744{,}073{,}709{,}551{,}615$ を見かけたら、
-1 番目へアクセスしようとした可能性が高いことを覚えておくとよい。
逆順ループをする場合のループ条件に注意
問題の内容次第では、以下のような逆順ループを書きたい場合がある。
for (int i=n-1; i>=0; i--)
int 型であれば問題ないが、i が size_t 型の場合、
i=0 の次が $18{,}446{,}744{,}073{,}709{,}551{,}615$ になり、
ループが継続してしまう。
for (size_t i=a.size()-1; i<a.size(); i--)
のように書くと防げる。
関連アルゴリズム
int型
最も代表的な符号付き整数型。
.size() の値を int 型へ代入してから扱う方法もある。
vector
要素数や添え字を扱うときに、size_t 型が使われる。
string型
文字数や添え字を扱うときに、size_t 型が使われる。