c++ string在循环中直接调用length()与定义变量后间接调用length()结果不同


#include <iostream>
#include <string>
#include <set>
#include <vector>

using namespace std;

class Solution 
{
public:
    int fun1(string s) 
    {
        int s_len = s.length();
        for (int i = 0; i < s.length() - 1; i++)
            return 1;
        return 2;
    }
    int fun2(string s) 
    {
        int s_len = s.length();
        for (int i = 0; i < s_len - 1; i++)
            return 1;
        return 2;
    }
    
};

int main()
{
    string s = "";
    Solution solution;
    cout << solution.fun1(s) << endl;
    cout << solution.fun2(s) << endl;
    return 0;
}

img

s.length()返回值类型是无符号的整型(比如std::size_t,下面以std::size_t为例),返回值是0
在计算表达式s.length() - 1时,会将1进行整型提升为std::size_t,结果是std::size_t(-1),注意是无符号整型
当比较i < s.length() - 1时,i的值也会被整型提升为std::size_t,所以当i=0时,std::size_t(0) < std::size_t(-1)结果为真,循环执行一次,因此fun1()返回1
fun2()中,s_len = 0, 而且i < s_len - 1都是有符号整型int类型,不存在整型提升,因此int(0) < int(-1)为假,跳过循环,fun2()返回2

string.length()的返回值是无符号数,实测是unsigned long。所以和 i 比较的时候会被转换成有符号数,s.length()-1是负数会变成18446744073709551615,所以循环会被执行。而fun2中 s_len=s.length()的时候数值没有发生改变。
【C++】string类的size()和length()的返回值是无符号数_Magnum的博客-CSDN博客

注意了,length的返回值不是int,而是size_t