#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
std::string qaz{};
vector <size_t> index ;
cout <<"qaz: "<<qaz<<" length: "<<qaz.length()<<"\n";
for (size_t i{0}; i<= ( qaz.length()-2);i )
{ cout<<"Entered"<<i<<"\n";
cout<<"Exited"<<i<<"\n";}
return 0;
}
//這里qaz是一個空字串,所以qaz.length() == 0(所以qaz.length()-2 == -2)并且i被初始化為0所以我預計我們不會進入回圈。但是在運行它時,我發現它在無限回圈中進行。為什么?請幫幫我。
uj5u.com熱心網友回復:
請參閱檔案size_t:
std::size_t是運算子結果的無符號整數型別sizeof
(強調我的。)
此外,string::length回傳 a size_ttoo 1。
但是,即使不是這種情況,當將有符號值與無符號值進行比較時,有符號值也會在比較之前轉換為無符號值,如本答案中所述。
(size_t)0 - 2將像無符號一樣下溢size_t,因此它的最小值為零,導致一個很大的數字,通常是2 2 32 -2 或 2 64 -2,具體取決于處理器架構。讓我們選擇后者,那么你將得到 18,446,744,073,709,552,000 作為結果。
現在,查看結果0 <= 18446744073709552000可以看到零明顯小于或等于 18.4 quintillion,因此滿足回圈條件。事實上,回圈不是無限的,它會精確回圈 18,446,744,073,709,552,001 次,但確實你可能不想等待它最終到達終點。
解決方案是通過比較i y <= x而不是i <= x - y3來避免下溢,即i 2 <= qaz.length()。然后你就會有2 <= 0哪個是假的。
1:從技術上講,它回傳一個std::allocator<char>::size_type但定義為std::size_t。
2:準確的說是SIZE_MAX - (2 - 1)ie SIZE_MAX - 1(見limits)。就數值而言,它也可能是 2 16 -2 - 例如在 ATmega328P 微控制器上 - 或其他值,但在當前時間點在臺式計算機上獲得的體系結構上,它很可能是兩個 I提及。這取決于std::size_t型別的寬度。如果它是 X 位寬,你會得到 2 X -n for (size_t)0 - nfor 0<n<2 X。但是,從 C 11 開始,它保證std::size_t不小于 16 位寬。
3:但是,在不太可能的情況下,您的長度非常大,特別是至少上面計算的數字 2 X -2 或更大,這將導致溢位。但在那種情況下,你的整個邏輯就會有缺陷,你需要一種不同的方法。我認為無論如何都不會是這種情況,因為std::ssize支持意味著字串長度必須有一個未使用的位才能重新用作符號位,但我認為這個答案已經足夠深入各個兔子洞了。
uj5u.com熱心網友回復:
length()回傳無符號值,不能低于零。0u - 2環繞并變成非常大的數字。
改為使用i 2 <= qaz.length()。
uj5u.com熱心網友回復:
問題是size_t未簽名。length()回傳無符號的字串size_type,而且很可能也是size_t。當字串大小<2然后length() -2環繞以產生一個大的無符號值時。
由于 C 20 有std::ssize回傳有符號值。盡管您還必須調整型別i以獲得正確的迭代次數,i < -2但條件是:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
std::string qaz{};
vector <size_t> index ;
cout <<"qaz: "<<qaz<<" length: "<<qaz.length()<<"\n";
for (int i{0}; i<= ( std::ssize(qaz)-2);i )
{
cout<<"Entered"<<i<<"\n";
cout<<"Exited"<<i<<"\n";
}
}
或者留在 unsigneds 并使用i 2 <= qaz.length().
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/445349.html
標籤:C
