Как, если (cin) {while (cin) ... работает? - PullRequest
0 голосов
/ 07 сентября 2018
int main () {
int num1, num2;
int cnt = 1;
    if (cin >> num1){       
        while (cin >> num2){
              if (num1==num2){
                  ++cnt;
              } else {
                  cout << num1 << " is " << cnt << " times" << endl;
                  cnt = 1;
                  num1 = num2;
              }
        }
    }
    cout << num1 << " is " << cnt << "-times" << endl;
}

Этот код принимает строку чисел и выводит, сколько раз было введено каждое число. Я не понимаю, почему существует num1=num2. С его удалением программа выводит первый введенный номер, что наводит меня на мысль, что я не знаю, как cin работает в циклах.

Теперь я думаю, что первая цифра входит в if (cin >> num1),, и она продолжает сидеть здесь, а следующие же цифры не перезаписывают num1 целое число. Вторая и остальные цифры входят в while (cin >> num2), перезаписывая его каждый раз, пока не появится другое число, что заставляет else выполняться и выводит число, которое все время хранилось в num1.

С num1=num2 он меняется num1 в if(cin>> num1) и все начинается снова. Я прав?

Что также странно, что самый последний кут может быть уверен внутри первого if тела, а может и нет, он все равно работает ...

Edit1: с num1 = num2; Я ввожу 1 1 2 2 3 3 3, одной строкой выводит

1 is 2 times

2 is 2 times

3 is 3 times. 

без num1 = num1;

1 is 2 times

1 is 1 times

1 is 1 times

1 is 1 times

1 is 1 times

Ответы [ 4 ]

0 голосов
/ 07 сентября 2018

Первое, если if (cin >> num1) проверяет, был ли вход (ожидает ввода) в num1, только тогда он продолжит цикл.

Затем он ждет второго ввода в num2 и входит в цикл, если вход пуст.

Затем он сравнивает два входа. Если они одинаковые ... это увеличивает счетчик. В противном случае он будет выводить, сколько раз один и тот же вход был обнаружен в строке , а затем изменить сравниваемый вход на последнее введенное значение и повторить цикл, ожидая ввода.

Так что он сравнивает, сколько раз за другим вы предоставляете один и тот же ввод ...

В основном, если ввод:

5
5
5
1

Выход будет "5 в 3 раза"

и если ввод

1
5
5
5

Вывод будет "1 - 1 раз"

0 голосов
/ 07 сентября 2018
#include <iostream>

int main () {
    int num1, num2;
    int cnt = 1;
    if (std::cin >> num1) { // if a valid integer can be extracted from cin
        while (std::cin >> num2) { // do as long as valid integers are extracted from cin
            if (num1 == num2) { // if the first extracted int matches the next one
                ++cnt; // increase the count
            }
            else { // if it is a different int then do some output and
                std::cout << num1 << " is " << cnt << " times\n";
                cnt = 1; // reset the counter and
                num1 = num2; // remember the new extracted number for
                             // the next iteration of the while-loop
                             // since only num2 will be read again from cin
            }
        }
    }
    std::cout << num1 << " is " << cnt << "-times\n";
}

Поскольку последняя строка в main() не имеет смысла, если нет действительного ввода, который я бы рекомендовал для досрочного выхода:

#include <cstdlib>
#include <iostream>

int main () {
    // ...
    if (!( std::cin >> num1 ))
        return EXIT_FAILURE;

    while (std::cin >> num2) {
        if (num1 == num2) {
    //  ...

также снижает уровень отступов и, следовательно, улучшает читаемость.

0 голосов
/ 07 сентября 2018

cin >> num1 пытается прочитать число из стандартного ввода в переменную num1. Если это удастся, тело if будет выполнено. В противном случае (например, если пользователь ввел что-то отличное от числа или сразу нажал Ctrl-d / Ctrl-z), мы сразу переходим к коду после if. Это происходит ровно один раз.

cin >> num2 делает то же самое с переменной num2, за исключением того, что на этот раз она находится внутри while вместо if. Таким образом, если операции ввода завершаются успешно, выполняется тело цикла while, и затем cin >> num2 выполняется снова, пока в конечном итоге не завершится неудачей.

Я не понимаю, почему существует num1=num2.

Как я уже сказал, cin >> num1 выполняется только один раз (это не внутри цикла). Поэтому, если вы никогда не назначите num1 заново, оно всегда будет сохранять первое введенное значение. Но вы не хотите этого, вы хотите, чтобы оно содержало значение, которое вы в данный момент считаете. Вот почему это назначение есть.

При num1 = num2 он меняет num1 в if (cin >> num1), и все начинается снова. Я прав?

Нет, cin >> num1 никогда не выполняется снова. Это не внутри петли. Только cin >> num2 выполняется несколько раз, потому что эта часть цикла while.

Что также странно, что самый последний кут может быть уверен внутри первого, если тело, а может и нет, оно все равно работает ...

Если первая операция ввода не удалась, она сразу же переместится наружу. Если есть оператор cout, это будет означать, что он будет выполнен, даже если первый ввод не удался. В этом случае num1 будет неинициализирован, поэтому его использование вызовет неопределенное поведение. Поэтому это утверждение не должно быть за пределами if.

0 голосов
/ 07 сентября 2018

Я понимаю, что код выполняет подсчет и отображает число последовательных появлений числа, чтобы оно не работало для неупорядоченного списка.

Тем не менее, как этоработает по существу следующим образом:

  1. Посмотрите, есть ли номер, доступный в потоке, и, если это так, сохраните его в num1.
  2. . Для каждого следующего числа прочитайтечисло до num2.
  3. Если num1 и num2 одинаковы, увеличить счетчик.
  4. Если, однако, числа не совпадают: выведите счетчик повторений,установите счетчик в 1, и измените первое число сравнения (num1) на вновь прочитанное число (num2).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...