Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

10. Проанализируйте пример битового поля из раздела 25.5.5. Напишите пример, в котором инициализируется структура PPN, затем выводится на печать значение каждого ее поля, затем изменяется значение каждого поля (с помощью присваивания) и результат выводится на печать. Повторите это упражнение, сохранив информацию из структуры PPN в 32-битовом целом числе без знака, и примените операторы манипулирования битами (см. раздел 25.5.4) для доступа к каждому биту в этом слове.

11. Повторите предыдущее упражнение, сохраняя биты к объекте класса bitset<32>.

12. Напишите понятную программу для примера из раздела 25.5.6.

13. Используйте алгоритм TEA (см. раздел 25.5.6) для передачи данных между двумя компьютерами. Использовать электронную почту настоятельно не рекомендуется.

14. Реализуйте простой вектор, в котором могут храниться не более N элементов, память для которых выделена из пула. Протестируйте его при N==1000 и целочисленных элементах.

15. Измерьте время (см. раздел 26.6.1), которое будет затрачено на размещение 10 тысяч объектов случайного размера в диапазоне байтов [1000:0], с помощью оператора new; затем измерьте время, которое будет затрачено на удаление этих элементов с помощью оператора delete. Сделайте это дважды: один раз освобождая память в обратном порядке, второй раз — случайным образом. Затем выполните эквивалентное задание для 10 тысяч объектов размером 500 байт, выделяя и освобождая память в пуле. Потом разместите в диапазоне байтов [1000:0] 10 тысяч объектов случайного размера, выделяя память в стеке и освобождая ее в обратном порядке. Сравните результаты измерений. Выполните каждое измерение не менее трех раз, чтобы убедиться в согласованности результатов.

16. Сформулируйте двадцать правил, регламентирующих стиль программирования (не копируя правила из раздела 25.6). Примените их к программе, состоящей более чем из 300 строк, которую вы недавно написали. Напишите короткий (на одной-двух страницах) комментарий о применении этих правил. Нашли ли вы ошибки в программе? Стал ли код яснее? Может быть, он стал менее понятным? Теперь модифицируйте набор правил, основываясь на своем опыте.

17. В разделах 25.4.3-25.4.4 мы описали класс Array_ref, обеспечивающий более простой и безопасный доступ к элементам массива. В частности, мы заявили, что теперь наследование обрабатывается корректно. Испытайте разные способы получить указатель Rectangle* на элемент массива vector, используя класс Array_ref, не прибегая к приведению типов и другим операциям с непредсказуемым поведением. Это должно оказаться невозможным.

Послесловие

Итак, программирование встроенных систем сводится, по существу, к “набивке битов”? Не совсем, особенно если вы преднамеренно стремитесь минимизировать заполнение битов как источник потенциальных ошибок. Однако иногда биты и байты системы приходится “набивать”; вопрос только в том, где и как. В большинстве систем низкоуровневый код может и должен быть локализован. Многие из наиболее интересных систем, с которыми нам пришлось работать, были встроенными, а самые интересные и сложные задачи программирования возникают именно в этой предметной области.

<p id="AutBody_Root507"><strong>Глава 26</strong></p><p>Тестирование</p>

“Я только проверил корректность кода, но не

тестировал его”.

Дональд Кнут (Donald Knuth)

В настоящей главе обсуждаются вопросы тестирования и проверки корректности работы программ. Это очень обширные темы, поэтому мы можем осветить их лишь поверхностно. Наша цель — описать некоторые практичные идеи и методы тестирования модулей, таких как функции и классы. Мы обсудим использование интерфейсов и выбор тестов для проверки программ. Основной акцент будет сделан на проектировании и разработке систем, упрощающих тестирование и его применение на ранних этапах разработки. Рассматриваются также методы доказательства корректности программ и устранения проблем, связанных с производительностью.

<p id="AutBody_Root508"><strong>26.1. Чего мы хотим</strong></p>

Проведем простой эксперимент. Напишите программу для бинарного поиска и выполните ее. Не ждите, пока дочитаете эту главу или раздел до конца. Важно, чтобы вы выполнили это задание немедленно! Бинарный поиск — это поиск в упорядоченной последовательности, который начинается с середины.

• Если средний элемент равен искомому, мы заканчиваем поиск.

• Если средний элемент меньше искомого, проводим бинарный поиск в правой части.

• Если средний элемент больше искомого, проводим бинарный поиск в левой части.

• Результат поиска является индикатором его успеха и позволяет модифицировать искомый элемент. Для этого в качестве такого индикатора используется индекс, указатель или итератор.

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных