int main( int nNumberOfArgs , char* pszArgs[ ] )
{
/* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */
setlocale (LC_ALL,".1251");
cout << "Эта программа содержит ошибки!\n" ;
int nSum ;
int nNums ;
/* Суммируем ряд чисел, пока пользователь не введёт отрицательное число, после чего выводим среднее */
nNums = 0 ;
while ( true )
{
/* Ввод очередного числа */
int nValue ;
cout << "Введите следующее число:" ;
cin >> nValue ;
cout << endl ;
/* Если это число отрицательное... */
if ( nValue < 0 )
{
/* ...то вывести среднее значение */
cout << "Среднее равно: "
<< nSum / nNums
<< endl ;
break ;
}
/* Введеённое число не отрицательно — добавляем его к накапливаемой сумме */
nSum += nValue ;
}
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
_________________
129 стр. Глава 10. Отладка программ на С++
После ввода этой программы создайте выполнимый файл ( клавиша ). Запустите эту программу и введите числа 1, 2 и 3, а затем -1. Вы ожидаете увидеть, что их среднее равно двум? Вместо этого очевидного результата будет выдано довольно непривлекательное сообщение об ошибке, показанное на рис. 10.1.
«Рис. 10.1 может отличаться в зависимости от используемых операционной системы и компилятора.»
[Помни!]
Рис. 10.1. Первоначальная версия программы содержит как минимум одну ошибку
Выявление "жучка" № 1...130
Очень сложно разобраться, в чём именно проблема, по столь неинформативному сообщению. Но в некоторых операционных системах попроще вы получите сообщение ( поверьте на слово ), в котором будет туманный намёк относительно деления на нуль. Впрочем, мы и сами можем догадаться о том, что проблема где-то рядом, поскольку ошибка произошла после того, как мы ввели отрицательное число, но до того, как на экран был выведен результат. Давайте ещё раз посмотрим на так и не выполнившуюся инструкцию:
cout << "Среднее равно: "
<< nSum / nNums
<< endl ;
«Кстати говоря, хотя это и единственное деление, использованное нами в программе, это ещё не означает, что ошибка именно в нём. Компилятор может сгенерировать команду деления в результате обработки некоторой иной инструкции, написанной программистом. Кроме того, делений хватает и в стандартной библиотеке С++.»
[Советы]
Давайте посмотрим, чему равно значение nNums перед выполнением деления, изменив код следующим образом:
while ( true )
{
cout << "nNums = " << nNums << endl ;
/* Остальная часть программы остаётся неизменной */
_________________
130 стр. Часть 2. Становимся функциональными программистами
Такое дополнение нашей программы приводит к следующему выводу на экран:
Эта программа содержит ошибки!
nNums = 0
Введите следующее число: 1
nNums = 0
Введите следующее число: 2
nNums = 0
Введите следующее число: 3
nNums = 0
Введите следующее число:
Как видите, nNums инициализировано нулевым значением, но оно не увеличивается в процессе ввода новых чисел. Это неверно, и именно в этом состоит ошибка в программе. Очевидно, что количество введённых чисел nNums должно увеличиваться, чего можно легко достичь, заменив цикл while циклом for:
for ( int nNums = 0 ; ; nNums++ )
Выявление "жучка" № 2...131