Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
19. Напишите программу, в которую сначала вводится набор пар, состоящих из имени и значения, например Joe 17 и Barbara 22. Для каждой пары занесите имя в вектор names, а число — в вектор scores (в соответствующие позиции, так что если names[7]=="Joe", то scores[7]==17). Прекратите ввод, введя строку NoName 0. Убедитесь, что каждое имя уникально, и выведите сообщение об ошибке, если имя введено дважды. Выведите на печать все пары (имя, баллы) по одной в строке.
20. Измените программу из упр. 19 так, чтобы при вводе имени она выводила соответствующее количество баллов или сообщение "name not found".
21. Измените программу из упр. 19 так, чтобы при вводе целого числа она выводила все имена студентов, получивших заданное количество баллов или сообщение "score not found".
Послесловие
С философской точки зрения вы уже можете делать с помощью компьютера все, что захотите, — остальное детали! Разумеется, важность деталей и практических навыков несомненна, поскольку вы только начинаете программировать. Но мы говорим серьезно. Инструменты, представленные в главе, позволяют описывать любые вычисления: у вас может быть столько переменных, сколько вам нужно (включая векторы и строки), вы можете выполнять арифметические операции, сравнения, а также выбор и итерации. С помощью этих примитивов можно выразить любые вычисления. Вы можете вводить и выводить числа и строки в виде текста (и даже графиков). Можете даже организовать вычисления в виде набора функций. Осталось только научиться писать хорошие программы, т.е. правильные, понятные и эффективные. Не менее важно, чтобы вы смогли научиться этому, затратив разумное количество сил.
Глава 5
Ошибки
“Я понял, что с этого момента большую часть моей жизни
буду искать и исправлять свои же ошибки”.
Морис Уилкс (Maurice Wilkes, 1949)
В этой главе обсуждаются вопросы, связанные с корректностью программ, а также с ошибками и методами исправления ошибок. Если вы новичок, то обсуждение покажется вам несколько абстрактным, а иногда слишком подробным. Неужели обработка ошибок настолько важна? Да! И так или иначе вы должны научиться этому. Прежде чем приступать к разработке программ, предназначенных для других людей, мы попытаемся показать, что значит “думать, как программист”, т.е. как сочетать самые абстрактные стратегии с тщательным анализом деталей и альтернатив.
5.1. Введение
В предыдущих главах мы часто упоминали об ошибках и, выполняя задания и упражнения, вы уже отчасти поняли почему. При разработке программ ошибки просто неизбежны, хотя окончательный вариант программы должен быть безошибочным или, по крайней мере, не содержать неприемлемых ошибок.
Существует множество способов классификации ошибок. Рассмотрим пример.
• Ошибки во время компиляции. Это ошибки, обнаруженные компилятором. Их можно подразделить на категории в зависимости от того, какие правила языка он нарушают:
• синтаксические ошибки;
• ошибки, связанные с типами.
• Ошибки во время редактирования связей. Это ошибки, обнаруженные редактором связей при попытке объединить объектные файлы в выполняемый модуль.
• Ошибки во время выполнения. Это ошибки, обнаруженные в ходе контрольных проверок выполняемого модуля. Эти ошибки подразделяются на следующие категории:
• ошибки, обнаруженные компьютером (аппаратным обеспечением и/или операционной системой);
• ошибки, обнаруженные с помощью библиотеки (например, стандартной);
• ошибки, обнаруженные с помощью программы пользователя.
• Логические ошибки. Это ошибки, найденные программистом в поисках причины неправильных результатов.
Соблазнительно сказать, что задача программиста — устранить все ошибки. Разумеется, это было бы прекрасно, но часто этот идеал оказывается недостижимым. На самом деле для реальных программ трудно сказать, что подразумевается под выражением “все ошибки”. Например, если во время выполнения своей программы мы выдернем электрический шнур из розетки, то следует ли это рассматривать как ошибку и предусмотреть ее обработку? Во многих случаях совершенно очевидно, что ответ будет отрицательным, но в программе медицинского мониторинга или в программе, управляющей телефонными переключениями, это уже не так. В этих ситуациях пользователь вполне обоснованно может потребовать, чтобы система, частью которой является ваша программа, продолжала выполнять осмысленные действия, даже если исчезло энергопитание компьютера или космические лучи повредили его память. Основной вопрос заключается в следующем: должна ли программа сама обнаруживать ошибки?
Если не указано явно, будем предполагать, что ваша программа удовлетворяет следующим условиям.
1. Должна вычислять желаемые результаты при всех допустимых входных данных.
2. Должна выдавать осмысленные сообщения обо всех неправильных входных данных.
3. Не обязана обрабатывать ошибки аппаратного обеспечения.
4. Не обязана обрабатывать ошибки программного обеспечения.
5. Должна завершать работу после обнаружения ошибки.
Программы, для которых предположения 3–5 не выполняются, выходят за рамки рассмотрения нашей книги. В то же время предположения 1 и 2 являются частью основных профессиональных требований, а профессионализм — это именно то, к чему мы стремимся. Даже если мы не всегда соответствуем идеалу на 100%, он должен существовать.
При создании программы ошибки естественны и неизбежны. Вопрос лишь в том, как с ними справиться. По нашему мнению, при разработке серьезного программного обеспечения попытки обойти, найти и исправить ошибки занимают более 90% времени. Для программ, безопасность работы которых является первоочередной задачей, эти усилия займут еще больше времени. В маленьких программах легко избежать ошибок, но в больших вероятность ошибок возрастает.
Мы предлагаем три подхода к разработке приемлемого программного обеспечения.
• Организовать программное обеспечение так, чтобы минимизировать количество ошибок.
• Исключить большинство ошибок в ходе отладки и тестирования.
• Убедиться, что оставшиеся ошибки не серьезны.
Ни один из этих подходов сам по себе не позволяет полностью исключить ошибки, поэтому мы будем использовать все три.
При разработке надежных программ, т.е. программ, которые делают то, для чего предназначены при допустимом уровне ошибок, большую роль играет опыт. Пожалуйста, не забывайте, что в идеале программы всегда должны работать правильно. Разумеется, на практике мы можем лишь приблизиться к идеалу, но отказ от трудоемких попыток приблизиться к идеалу заслуживает безусловного осуждения.
5.2. Источники ошибок
Перечислим несколько источников ошибок.
• Плохая спецификация. Если мы слабо представляем себе, что должна делать программа, то вряд ли сможем адекватно проверить все ее “темные углы” и убедиться, что все варианты обрабатываются правильно (т.е. что