2015-05-23 5 views
0

Я считаю, что две петли ниже одинаковы, никто не знает, почему они работают по-разному в случае | s1 | > | s2 |?C++ for loop странное поведение

string s1 = "abcd"; 
string s2 = "abc"; 

int s1len = s1.length() 
int s2len = s2.length() 

for (int i = 0; i <= s2len - s1len; i++) { 
    // it will never calls (as expected, since 3 - 4 = -1) 
} 

for (int i = 0; i <= s2.length() - s1.length(); i++) { 
    // it calls once (which is strange) 
} 
+2

Вы забыли (а) ',' на оба ваших длины заданий, и (б) [с ** предупреждения ** Ваш компилятор должен предоставить вам] (http://coliru.stacked-crooked.com/a/022bba8b76446e64) для возможных проблем. Если вы не видите эти предупреждения, время для проверки уровня предупреждения. – WhozCraig

+0

Сделал это из памяти без тестирования, но полезно знать, спасибо! – user3537411

ответ

5

std::string::length() возвращает целочисленный тип без знака. Неподписанные межголовые типы следуют за модульной арифметикой, так что -1 сопоставляет с большим значением этого типа. Это означает, что вычитание во втором цикле дает очень большое число вместо отрицательного.

Вы могли бы попытался это выяснить это сами:

std::cout << s2.length() - s1.length() << std::endl; 
+0

Спасибо! Is 'for (int i = 0; i <= (int) s2.length() - (int) s1.length(); i ++) {' лучший способ рассчитать его без дополнительных переменных? – user3537411

+1

@ user3537411 «лучший способ» - относительный термин, потому что 'int' обычно не охватывает диапазон' std :: string :: size_type', который обычно является 'std :: size_t'. Длина строки может быть такой большой, что она не вписывается в 'int'. Так что это действительно зависит от того, что вы хотите сделать. Одним из вариантов было бы вычисление абсолютной разницы, а затем ветвь в зависимости от того, какая из длин больше. – juanchopanza

Смежные вопросы