v.size()の型がsize_tであることが原因と推測しますが、このような違いが出る理由がはっきり分からない
短い答え:質問文で言及がある通り、v.size()の型がsize_t(≒intではない)ことが直接原因です。前者は中間結果をint型に代入していますが、後者はそのような型変換が生じないという違いがあります。
長い答え:C++言語における算術変換ルール、動作環境のint型およびsize_t型のサイズ(ビット幅)に依存した結果です。おそらく、32bit Windowsアプリケーションとしてビルド&実行されたのではないでしょうか?
あなたが試した動作環境(OS、コンパイラ)では、下記のように定義されているはずです。
int=32bit 符号付き整数型
size_t=32bit 符号なし整数型
ここからは説明のため、T型の値xをx@Tと表記します。
c++
1int tmp = v.size() - 1;
2printf("%d\n", tmp / 3);
- 1行目:式
v.size()は0@size_tを返します。減算-両辺の型をそろえるためリテラル1@intは1@size_tに変換され、式0@size_t - 1@size_tの演算結果(-1@size_t相当)は符号無し型のため(2^32)-1=4294967295@size_tとなります。これをint型にキャストすると-1@intに戻り、変数tmpには-1@intが代入されます。
- 2行目:式
-1@int / 3@intの演算結果は0@intです。
c++
1printf("%zu\n", (v.size() - 1) / 3);
2// size_t型には書式"%zu"が対応する(修正済み)
- 部分式
(v.size() - 1)の演算結果が4294967295@size_tとなるまでは前述の通り。
- 式
4294967295@size_t / 3@intの除算/両辺の型をそろえるためリテラル3@intは3@size_tに変換され、演算結果は1431655765@size_tとなります。
2020/06/01 07:31
2020/06/01 12:08