for循环中的怪异std :: string :: size() [英] Weird std::string::size() in a for loop
问题描述
如果我使用 input.size()-1
作为for循环条件,程序将打印进入循环".
The program will print "Entered the loop" if I use input.size() - 1
as the for loop condition.
std::string input;
input = {""};
int i = 0;
for (; i < input.size() - 1; ++i)
{
cout << "Entered the loop" << endl;
}
但是,如果我将 input.size()-1
的值传递给整数( checksize
):
However, if I pass the value of input.size() -1
to an integer (checksize
):
std::string input;
input = {""};
int checksize = input.size() - 1;
int i = 0;
for (; i < checksize; ++i)
{
cout << "Entered the loop" << endl;
}
然后程序将不会进入循环并且不会显示进入循环"
then the program will not go into the loop and will not print "Entered the loop"
我想知道为什么会这样吗?看来这两段代码对我来说是相同的.
I was wondering why this happen? It seems the two pieces of code are the same to me.
推荐答案
您是 unsigned 整数()的受害者:)
You are a victim of unsigned integers :)
std :: string :: size()
返回一个无符号整数(类型与 size_t
等效).
std::string::size()
returns an unsigned integer (of type equivalent to size_t
).
当编译器评估 input.size()-1
时,这种类型变为 size_t(0)-1
,并且由于计算是通过完成的unsigned 整数,而不是-1,您将得到一个非常大的整数(MSVC 32位编译器打印 4294967295
,它对应于最大的32位unsigned整数值 2 ^32-1
).
When the compiler evaluates input.size() - 1
, this kind of becomes size_t(0) - 1
, and since the computation is done with unsigned integers, instead of -1 you get a very big integer number (MSVC 32-bit compiler prints 4294967295
, which corresponds to the maximum 32-bit unsigned integer value 2^32 - 1
).
所以这个循环:
for (int i = 0; i < input.size() - 1; ++i)
等效于:
for (int i = 0; i < /* very big positive number */; ++i)
这将多次打印您的消息.
which will print your message many times.
相反,在第二种情况下,当您评估 input.size()-1
然后将其分配给 int
变量(已被 signed
默认情况下,编译器仍将 size_t(0)-1
计算为非常大的正整数,但随后该数字将转换为( signed
) int
,导致使用 -1
初始化 checksize
,并且永远不会执行循环:
Instead, in the second case, when you evaluate input.size() - 1
and then assign it to an int
variable (which is signed
by default), the compiler still computes size_t(0) - 1
as a very big positive integer number, but then this number is converted to a (signed
) int
, resulting in checksize
being initialized with -1
, and your loop is never executed:
for (int i = 0; i < checksize /* -1 */; ++i)
考虑此可编译代码:
Considering this compilable code:
#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
循环条件会得到警告:
If you compile its CASE1
with MSVC and /W4
(warning level 4, which I highly suggest), you get a warning for your for
loop condition:
cl /EHsc /W4 /nologo /DCASE1 test.cpp
test.cpp(10) : warning C4018: '<' : signed/unsigned mismatch
通常会指出您的代码有问题.
which usually points to you that something is wrong with your code.
相反,在没有 CASE1
的情况下进行编译时,不会给出警告,并显示以下输出(这表明从未执行 for
循环的主体):
Instead, compiling without CASE1
, gives no warnings and the following output (which shows that the for
loop's body is never executed):
cl /EHsc /W4 /nologo test.cpp
input.size() - 1 == 4294967295
SIZE_MAX == 4294967295
checkSize == -1
这篇关于for循环中的怪异std :: string :: size()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!