如果我使用 input.size() - 1
作为 for 循环条件,程序将打印“Entered the loop”。
std::string input;
input = {""};
int i = 0;
for (; i < input.size() - 1; ++i)
{
cout << "Entered the loop" << endl;
}
但是,如果我将 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;
}
那么程序就不会进入循环,也不会打印“Entered the loop”
我想知道为什么会这样?这两段代码对我来说似乎是一样的。
最佳答案
你是无符号整数的受害者:)
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)
相当于:
for (int i = 0; i < /* very big positive number */; ++i)
它将多次打印您的消息。
相反,在第二种情况下,当您评估 input.size() - 1
并将其分配给 int
变量(signed
默认情况下),编译器仍将 size_t(0) - 1
计算为一个非常大的正整数,但随后该数字将转换为(有符号
) int
,导致 checksize
被初始化为 -1
,并且您的循环永远不会执行:
for (int i = 0; i < checksize /* -1 */; ++i)
考虑这个可编译代码:
#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
}
如果您使用 MSVC 和 /W4
编译它的 CASE1
(警告级别 4,我强烈建议),您会收到针对您的 for
循环条件的警告:
cl /EHsc /W4 /nologo /DCASE1 test.cpp test.cpp(10) : warning C4018: '<' : signed/unsigned mismatch
这通常表明您的代码有问题。
相反,在没有 CASE1
的情况下进行编译,不会给出任何警告和以下输出(这表明 for
循环体从未被执行):
cl /EHsc /W4 /nologo test.cpp input.size() - 1 == 4294967295 SIZE_MAX == 4294967295 checkSize == -1
关于c++ - for 循环中奇怪的 std::string::size(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37090091/