lig*_*rek 2 c++ size unsigned for-loop unsigned-integer
如果我input.size() - 1用作for循环条件,程序将打印"进入循环" .
std::string input;
input = {""};
int i = 0;
for (; i < input.size() - 1; ++i)
{
cout << "Entered the loop" << endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将值传递input.size() -1给整数(checksize):
std::string input;
input = {""};
int checksize = input.size() - 1;
int i = 0;
for (; i < checksize; ++i)
{
cout << "Entered the loop" << endl;
}
Run Code Online (Sandbox Code Playgroud)
然后程序将不会进入循环并且不会打印"进入循环"
我想知道为什么会这样?看来这两段代码对我来说是一样的.
你是无符号整数的受害者:)
std::string::size()返回无符号整数(类型等于size_t).
当编译器评估时input.size() - 1,这种情况变为size_t(0) - 1,并且由于计算是使用无符号整数完成的,而不是-1,因此得到一个非常大的整数(MSVC 32位编译器打印4294967295,对应于最大32位无符号整数值)2^32 - 1).
所以这个循环:
for (int i = 0; i < input.size() - 1; ++i)
Run Code Online (Sandbox Code Playgroud)
有点像:
for (int i = 0; i < /* very big positive number */; ++i)
Run Code Online (Sandbox Code Playgroud)
这将打印信息许多倍.
相反,在第二种情况下,当你评估input.size() - 1,然后将其分配给一个int变量(它是signed通过缺省值),编译器仍然计算size_t(0) - 1作为一个非常大的正整数,但随后这个号码被转换为(signed)int,从而产生checksize被用-1,初始化,你的循环永远不会执行:
for (int i = 0; i < checksize /* -1 */; ++i)
Run Code Online (Sandbox Code Playgroud)
考虑这个可编译的代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input;
#ifdef CASE1
for (int i = 0; i < input.size() - 1; ++i)
{
cout << "Entered the loop\n";
}
#else
cout << "input.size() - 1 == " << (input.size() - 1) << '\n';
cout << "SIZE_MAX == " << SIZE_MAX << '\n';
int checkSize = input.size() - 1;
cout << "checkSize == " << checkSize << '\n';
for (int i = 0; i < checkSize; ++i)
{
cout << "Entered the loop\n";
}
#endif
}
Run Code Online (Sandbox Code Playgroud)
如果您编译它CASE1与MSVC和/W4(警戒水位4,我强烈建议),你会得到一个警告,为您的for循环条件:
Run Code Online (Sandbox Code Playgroud)cl /EHsc /W4 /nologo /DCASE1 test.cpp test.cpp(10) : warning C4018: '<' : signed/unsigned mismatch
通常会向您指出您的代码出了问题.
相反,编译没有CASE1,没有提供警告和以下输出(这表明for循环的主体永远不会被执行):
Run Code Online (Sandbox Code Playgroud)cl /EHsc /W4 /nologo test.cpp input.size() - 1 == 4294967295 SIZE_MAX == 4294967295 checkSize == -1