Выявление "жучка" № 2...131 

Теперь, когда найдена и исправлена ошибка № 1, можно запустить программу, введя числа, заставившие её в прошлый раз аварийно завершиться. На этот раз сообщение об ошибке не появится и программа вернёт нулевой код выхода, но будет работать не так, как ожидалось. Вместо так горячо ожидаемой двойки будет выведено какое-то нелепое число.

    Эта программа содержит ошибки:

    Введите следующее число: 1

    Введите следующее число: 2

    Введите следующее число: 3

    Введите следующее число: -1

    Среднее равно: 229523

Очевидно, какая-то из переменных — nNums или nSum ( а возможно, и обе ) содержит неверное значение. Для того чтобы исправить ошибку, необходимо узнать, какая именно из этих переменных содержит неверную информацию. Не помешало бы также знать, что содержится в переменной nValue, поскольку она используется для подсчёта суммы в nSum.

Для этого воспользуемся методом отладочной печати. Чтобы узнать значения nValue, nSum и nNums, перепишите тело цикла for так, как показано в следующем листинге ( версия программы имеется на прилагаемом компакт-диске в файле с именем ErrorProgram2.срр ).

      /* ErrorProgram — эта программа усредняла бы ряд чисел, если бы не содержала как минимум одну фатальную ошибку */

      #include <cstdio>

      #include <cstdlib>

      #include <iostream>

      using namespace std ;

      int main ( int nNumberofArgs , char* pszArgs[ ] )

      {

            /* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */

            setlocale (LC_ALL,".1251");

            cout << " Эта программа содержит ошибки!"

                    << endl ;

            /* Суммируем ряд чисел, пока пользователь не введёт отрицательное число, после чего выводим среднее */

            int nSum ;

            for ( int nNums = 0 ; ; nNums++ )

_________________

131 стр. Глава 10. Отладка программ на С++

            {

               /* Ввод следующего числа */

               int nValue ;

               cout << "Введите следующее число:" ;

               cin >> nValue ;

               cout << endl ;

               /* Если введённое число отрицательно... */

               if ( nValue < 0 )

               {

                   /* ...выводим результат усреднения */

                   cout << " Среднее равно: "

                           << nSum / nNums

                           << " " ;

                   break ;

               }

               /* Вывод отладочной информации */

               cout << "nSum = " << nSum << " " ;

               cout << "nNums= " << nNums << " " ;

               cout << "nValue= " << nValue << " " ;

               cout << endl ;

               /* Введённое число не отрицательно, суммируем его */

               nSum += nValue ;

           }

           /* Пауза для того, чтобы посмотреть на результат работы программы */

           system( "PAUSE" ) ; return 0 ;

    }

Обратите внимание на то, что информация о состоянии отслеживаемых переменных nValue, nSum и nNums выводится в каждом цикле.

Ответ программы на ввод уже привычных 1, 2, 3 и -1 приведён ниже. При первом же проходе nSum принимает какое-то несуразное значение, хотя оно должно равняться нулю ( поскольку к этой переменной пока что ничего не прибавлялось ).

    Эта программа содержит ошибки!

    Введите следующее число:1

    nSum = -858993460

    nNums = 0

    nValue= 1

    Введите следующее число:2

    nSum = -858993459

    nNums= 1

    nValue= 2

    Введите следующее число:3

    nSum = -858993457

    nNums = 2

    nValue= 3

    Введите следующее число:

_________________

132 стр. Часть 2. Становимся функциональными программистами

Внимательно присмотревшись к программе, можно заметить, что nSum была объявлена, но не проинициализирована. Для того чтобы исправить эту ошибку, объявление переменной необходимо изменить следующим образом:

        int nSum = 0 ;

Примечание. Пока переменная не проинициализирована, её значение непредсказуемо.

«Теперь, когда вы нашли все ошибки, перепишите программу так, как показано в следующем листинге ( эта программа имеется на прилагаемом компакт-диске в файле ErrorProgram3.срр )

[Диск]

    /* ErrorProgram — эта программа усредняет ряд чисел и не содержит ошибок */

    #include <cstdio>

    #include <cstdlib>

    #include <iostream>

    using namespace std ;

    int main( int nNumberofArgs , char* pszArgs[ ] )

    {

            /* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */

            setlocale (LC_ALL,".1251");

        /* Суммируем ряд чисел, пока пользователь не введёт отрицательное число, после чего выводим среднее */

        int nSum = 0 ;

        for ( int nNums = 0 ; ; nNums++ )

        {

            /* Ввод следующего числа: */

            int nValue ;

            cout << "Введите следующее число:" ;

            cin >> nValue ;

            cout << endl ;

            /* Если введённое число отрицательно... */

            if ( nValue < 0 )

            {

                /* ...выводим усреднённое значение */

                cout << " Среднее равно: "

                        << nSum / nNums

                        << " " ;

                break ;

            }

            /* Введённое число не отрицательно, суммируем его */

            nSum += nValue ;

        }

        /* Пауза для того, чтобы посмотреть на результат работы программы */

        system( "PAUSE" ) ; return 0 ;

    } 

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

    Введите следующее число: 1

    Введите следующее число: 2

    Введите следующее число: 3

    Введите следующее число: -1

    Среднее равно: 2

    Press any key to continue...

_________________

133 стр. Глава 10. Отладка программ на С++