为什么这段代码打印 "YES" 无限次,而它应该打印 "NO" 一次

Why this code is printing "YES" infinite number of times while it should have printed "NO" one time

对于 s="0" 和 k=20,此代码无限次打印 YES,但 for 循环条件 (0<=1-20) 不成立。它应该打印不。请帮助我。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    string s;
    cin>>s;
    int k;
    cin>>k;
    for(int i=0;i<=s.size()-k;++i){
        cout<<"YES"<<endl;
    }
    cout<<"NO"<<endl;
    return 0;
}

简短的回答是:无符号整数下溢。

为了看得更清楚,让我们将值赋给类型为size_t的变量(即s.size() returns的类型):

const size_t ssize = s.size();
const size_t ssize_minus_k = ssize-k;
cout << "ssize=" << ssize << " ssize_minus_k=" << ssize_minus_k << endl;
for(int i=0;i<=ssize_minus_k;++i){
    cout<<"YES"<<endl;
}

.. 上面几行,程序的输出如下所示:

$ ./a.out 
0
20
ssize=1 ssize_minus_k=18446744073709551597
YES
YES
[...]

现在要解决这个问题,让我们将变量的类型从 size_t 更改为 ssize_t(注意额外的 s,意思是“有符号”):

const ssize_t ssize = s.size();
const ssize_t ssize_minus_k = ssize-k;
cout << "ssize=" << ssize << " ssize_minus_k=" << ssize_minus_k << endl;
for(int i=0;i<=ssize_minus_k;++i){
    cout<<"YES"<<endl;
}

...现在我们得到的行为更像我们所期望的:

$ ./a.out 
0
20
ssize=1 ssize_minus_k=-19
NO