for循环中的怪异std :: string :: size() [英] Weird std::string::size() in a for loop

查看:86
本文介绍了for循环中的怪异std :: string :: size()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆