- •1. Стиль 10
- •3. Проектирование и реализация 63
- •4. Интерфейсы 85
- •5. Отладка 115
- •6. Тестирование 134
- •7. Производительность 157
- •8. Переносимость 180
- •9. Нотация 203
- •Введение
- •Брайан в. Керниган
- •1.1. Имена
- •1.2. Выражения
- •Упражнение 1 -6
- •1.3. Стилевое единство и идиомы
- •1.4. Макрофункции
- •1.5. Загадочные числа
- •1.6. Комментарии
- •1.7. Стоит ли так беспокоиться?
- •Дополнительная литература
- •2.1. Поиск
- •2.2. Сортировка
- •2.3. Библиотеки
- •2.4. Быстрая сортировка на языке Java
- •2.5. "О большое"
- •2.6. Динамически расширяемые массивы
- •2.7. Списки
- •Упражнение 2-8
- •2.8. Деревья
- •Упражнение 2-15
- •2.10. Заключение
- •Дополнительная литература
- •Проектирование и реализация
- •3.1. Алгоритм цепей Маркова
- •3.2. Варианты структуры данных
- •3.3. Создание структуры данных в языке с
- •3.4. Генерация вывода
- •3.5.Java
- •Into the air. When water goes into the air it
- •3.7. Awk и Perl
- •3.8. Производительность
- •3.9. Уроки
- •Дополнительная литература
- •4. Интерфейсы
- •4.1. Значения, разделенные запятой
- •4.2. Прототип библиотеки
- •4.3. Библиотека для распространения
- •Упражнение 4-4
- •4.5 Принципы интерфейса
- •4.6. Управление ресурсами
- •4.7. Abort, Retry, Fail?
- •4.8. Пользовательские интерфейсы
- •Дополнительная литература
- •5. Отладка
- •5.1. Отладчики
- •5.2. Хорошие подсказки, простые ошибки
- •5.3, Трудные ошибки, нет зацепок
- •5.4. Последняя надежда
- •5.5. Невоспроизводимые ошибки
- •5.6. Средства отладки
- •5.7. Чужие ошибки
- •5.8. Заключение
- •Дополнительная литература
- •6. Тестирование
- •6.1. Тестируйте при написании кода
- •6.2. Систематическое тестирование
- •6.3. Автоматизация тестирования
- •6.4. Тестовые оснастки
- •6.5. Стрессовое тестирование
- •6.6. Полезные советы
- •6.7. Кто осуществляет тестирование?
- •6.8. Тестирование программы markov
- •6.9. Заключение
- •Дополнительная литература
- •7.Производительность
- •7.1. Узкое место
- •7.2. Замеры времени и профилирование
- •7.3. Стратегии ускорения
- •7.4. Настройка кода
- •7.5. Эффективное использование памяти
- •7.6. Предварительная оценка
- •7.7. Заключение
- •Дополнительная литература
- •8. Переносимость
- •8.1. Язык
- •8.2. Заголовочные файлы и библиотеки
- •8.3. Организация программы
- •8.4. Изоляция
- •8.5. Обмен данными
- •8.6. Порядок байтов
- •8.7. Переносимость и внесение усовершенствований
- •8.8. Интернационализация
- •8.9. Заключение
- •Дополнительная литература
- •9.1. Форматирование данных
- •9.2. Регулярные выражения
- •Упражнение 9-12
- •9.3. Программируемые инструменты
- •9.4. Интерпретаторы, компиляторы и виртуальные машины
- •9.5. Программы, которые пишут программы
- •9.6. Использование макросов для генерации кода
- •9.7. Компиляция "налету"
- •Дополнительная литература
- •Интерфейсы
- •Отладка
- •Тестирование
- •Производительность
- •Переносимость
5.7. Чужие ошибки
По правде говоря, большинству программистов не достается удовольствие разработки совершенно новой системы с нуля. Вместо этого больную часть времени они проводят, используя, поддерживая, изменяя и неизбежно отлаживал код, написанный другими людьми.
При отладке чухого кода остается в силе все, что мы сказали об отладке своего собственного кода. Перед тем как начать, однако, вы сначала должны добиться определенного понимания организации программы и хода мысли ее создателей. Термин "открытие", использованный в одном очень большой .программном проекте, является не такой уж плохой метафорой. Задачей является "открыть", что происходит в коде, который писали не вы.
Здесь очень сильно могут помочь инструментальные средства. Программы текстового поиска типа g rep помогут найти все места использования какого-нибудь имени. Перекрестные ссылки дают определенное представление о структуре программы. Граф, показывающий взаимные вызовы функций, ценен, если только он не очень велик. Пошаговый проход по программе с помощью отладчика поможет увидеть последовательность событий. Из истории ревизий программы можно узнать, что происходило в ней с течением времени. Частые изменения являются знаком того, что код был плохо понят или подвергался частой смене требований и поэтому потенциально содержит ошибки.
Иногда вам нужно найти ошибку в программе, которой вы не писали и исходного текста которой вы даже не имеете. В этом случае задачей является обнаружение и описание ошибки, причем так, чтобы вы смогли аккуратно сообщить о ней разработчику и в то же время, возможно, найти ее обходное решение.
Если вам кажется, что вы нашли ошибку в чужой программе, первым шагом следует убедиться, что это настоящая ошибка, чтобы не терять ни времени автора, ни собственного авторитета.
Если вы нашли ошибку в компиляторе, убедитесь, что это действительно ошибка компилятора, а не ошибка в вашем коде. Например, операция побитового сдвига вправо заполняет освобождающиеся биты нулем (логический сдвиг) или знаковым битом (арифметический сдвиг), а чем именно — в языках С и C++ не указано, поэтому новички иногда считают, что если конструкция типа
? i = -1;
? printf("%d\n", i > 1);
выдает неожиданный результат, то ошибка — в компиляторе. На самом деле это — вопрос переносимости, потому что данный оператор имеет право действовать по-разному на разных системах. Попробуйте проверить различные системы и посмотрите, что произойдет; обратитесь к описанию языка, чтобы удостовериться в правильной интерпретации результатов.
Убедитесь, что ошибка не нова. Используете ли вы последнюю версию программы. Есть ли список исправленных в ней ошибок? Большая часть программного обеспечения проходит серию выпусков; если вы нашли ошибку в версии 4.0b1, она может быть уже исправлена или заменена новой в версии 4.0b2. В любом случае немногие программисты испытывают достаточно энтузиазма, чтобы исправлять ошибки где-либо, кроме текущей версии программы.
Наконец, представьте самого себя в роли получателя вашего сообщения об ошибке. Вам следует предоставить автору максимально удобный тестовый пример, какой только сможете сделать. Будет не слишком хорошо, если ошибку можно показать только при больших объемах входных данных, или в очень сложных условиях, или при наличии множества дополнительных файлов. Сократите тест до минимального самодостаточного случая. Сообщите также дополнительную информацию, которая, возможно, связана с ошибкой, например версию самой программы, версию компилятора, операционной системы, состав оборудования на машине. Для ошибочной версии isprint, упомянутой в параграфе 5.4, мы предоставили такой тестовый случай:
/* тестовая программа для ошибки в isprint */
int main(void)
{
int с;
while (isprint(e = getctiar()) | | с != EOF)
printf("%c", c);
return 0;
}
Входными данными служила любая строка печатного текста, потому что на выходе появлялась только половина входа:
% echo 1234567890 | isprint_test
24680
%
Лучшие сообщения об ошибке — те, что требуют для демонстрации , ошибки только пары строк входных данных на стандартной конфигурации, а также те, что содержат и исправление соответствующей ошибки. Шлите такие сообщения об ошибке, какие вам хотелось бы получать самим.
