Чтение онлайн

на главную

Жанры

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

4.1. Вычисления

Все программы что-нибудь вычисляют; иначе говоря, они получают на вход какие-то данные и выводят какие-то результаты. Кроме того, само устройство, на котором выполняются программы, называется компьютером [5] . Эта точка зрения является правильной и обоснованной, пока мы придерживаемся широкой трактовки ввода и вывода.

Входная информация может поступать с клавиатуры, от мыши, с сенсорного экрана, из файлов, от других устройств ввода и других частей программы. К категории “другие устройства ввода” относятся наиболее интересные источники данных: музыкальные клавишные пульты, устройства

видеозаписи, датчики температуры, сенсоры цифровых видеокамер и т.п. Разнообразие этих устройств бесконечно.

5

От английского слова compute — вычислять. — Примеч. ред.

Для обработки входной информации программы обычно используют специальные данные, которые называют структурами данных (data structures) или их состояниями (states). Например, программа, имитирующая календарь, может содержать списки праздничных дней в разных странах и список ваших деловых свиданий. Некоторые из этих данных с самого начала являются частью программы, а другие возникают, когда программа считывает данные и извлекает из них полезную информацию. Например, программа, имитирующая календарь, может создавать список ваших деловых встреч по мере того, как вы будете вводить их в нее. В этом случае основной входной информацией являются запросы месяца и дня встречи (возможно, с помощью щелчка мышью) и ввод данных о деловых встречах (возможно, с помощью клавиатуры). Устройством вывода для этой программы является экран, на котором высвечиваются календарь и данные о назначенных встречах, а также кнопки и приглашения для ввода, которые программа может выводить на экран самостоятельно.

Входная информация может поступать от самых разных источников. Аналогично, результаты могут выводиться на разные устройства: на экран, в другие программы или части программы. К устройствам вывода относятся также сетевые интерфейсы, музыкальные синтезаторы, электрические моторы, генераторы энергии, обогреватели и т.п.

С программистской точки зрения наиболее важными и интересными категориями ввода-вывода являются “в другую программу” и “в другие части программы”. Большая часть настоящей книги посвящена последней категории: как представить программу в виде взаимодействующих частей и как обеспечить взаимный доступ к данным и обмен информацией. Это ключевые вопросы программирования. Проиллюстрируем их графически.

Аббревиатура I/O означает ввод-вывод. В данном случае вывод из одной части программы является вводом в следующую часть. Эти части программы имеют доступ к данным, хранящимся в основной памяти, на постоянном устройстве хранения данных (например, на диске) или передающимся через сетевые соединения. Под частями программы мы подразумеваем сущности, такие как функция, вычисляющая результат на основе полученных аргументов (например, извлекающая корень квадратный из числа с плавающей точкой), функция, выполняющая действия над физическими объектами (например, рисующая линию на экране), или функция, модифицирующая некую таблицу в программе (например, добавляющая имя в таблицу клиентов).

Когда мы говорим “ввод” и “вывод”, обычно подразумеваем, что в компьютер вводится или из компьютера выводится некая информация, но, как вы вскоре увидите, мы можем использовать эти термины и для информации, переданной другой части программы или полученной от нее. Информацию, которая является вводом в часть программы, часто называют аргументом, а данные, поступающие от части программы, — результатом.

Вычислением мы называем некое действие, создающее определенные результаты и основанное на определенных входных данных, например порождение результата (вывода), равного 49, на основе аргумента (ввода), равного 7, с помощью вычисления (функции) извлечения квадратного корня (см. раздел 4.5). Как курьезный факт, напомним, что до 1950-х годов компьютером [6] в США назывался человек, выполнявший вычисления, например бухгалтер, навигатор, физик. В настоящее время мы просто перепоручили большинство вычислений компьютерам (машинам), среди которых простейшими являются калькуляторы.

6

Вычислителем. — Примеч. ред.

4.2. Цели и средства

Цель программиста — описать вычисления, причем это должно быть сделано следующим образом:

• правильно;

• просто;

• эффективно.

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

быть как можно более простыми. Например, предположим, что вы написали идеальную программу для обучения основам арифметики детей в вашей местной школе, но ее внутренняя структура является слишком запутанной. На каком языке вы собираетесь общаться с детьми? На английском? Английском и испанском? А не хотели бы вы, чтобы вашу программу использовали в Финляндии? А в Кувейте? Как изменить естественный язык, используемый для общения с детьми? Если программа имеет слишком запутанную структуру, то логически простая (но на практике практически всегда очень сложная) операция изменения естественного языка для общения с пользователями становится непреодолимой.

Забота о правильности, простоте и эффективности программ возлагается на нас с той минуты, когда мы начинаем писать программы для других людей и осознаем ответственность за качество своей работы; иначе говоря, решив стать профессионалами, мы обязаны создавать хорошие программы. С практической точки зрения это значит, что мы не можем просто нагромождать инструкции, пока программа не заработает; мы должны разработать определенную структуру программы. Парадоксально, но забота о структуре и качестве кода часто является самым быстрым способом разработки работоспособных программ. Если программирование выполнено качественно, то хорошая структура программы позволяет сэкономить время на самой неприятной части работы: отладке. Иначе говоря, хорошая структура программы, продуманная на этапе разработки, может минимизировать количество сделанных ошибок и уменьшить объем времени, затрачиваемого на поиск таких ошибок и их исправление.

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

Абстракция. Этот способ предполагает сокрытие деталей, которые не являются необходимыми для работы с программой (детали реализации) за удобным и универсальным интерфейсом. Например, вместо изучения деталей сортировки телефонной книги (о методах сортировки написано множество толстых книг), мы можем просто вызвать алгоритм сортировки из стандартной библиотеки языка С++. Все, что нам нужно для сортировки, — знать, как вызывается этот алгоритм, так что мы можем написать инструкцию

sort(b, e)
, где
b
и
e
— начало и конец телефонной книги соответственно. Другой пример связан с использованием памяти компьютера. Непосредственное использование памяти может быть довольно сложным, поэтому чаще к участкам памяти обращаются через переменные, имеющие тип и имя (раздел 3.2), объекты класса
vector
из стандартной библиотеки (раздел 4.6, главы 17–19), объекты класса
map
(глава 21) и т.п.

• “Разделяй и властвуй”. Этот способ подразумевает разделение большой задачи на несколько меньших задач. Например, если требуется создать словарь, то работу можно разделить на три части: чтение, сортировка и вывод данных. Каждая из новых задач намного меньше исходной.

Чем это может помочь? Помимо всего прочего, программа, созданная из частей, обычно немного больше, чем программа, в которой все фрагменты оптимально согласованы друг с другом. Причина заключается в том, что мы плохо справляемся в большими задачами. Как правило, как в программировании, так и в жизни, — мы разбиваем их на меньшие части, полученные части разделяем на еще более мелкие, пока не получим достаточно простую задачу, которую легко понять и решить. Возвращаясь к программированию, легко понять, что программа, состоящая из 1000 строк, содержит намного больше ошибок, чем программа, состоящая из 100 строк, поэтому стоит разделить большую программу на части, размер которых меньше 100 строк. Для более крупных программ, скажем, длиной более 10 тыс. строк, применение абстракции и метода “разделяй и властвуй” является даже не пожеланием, а настоятельным требованием.

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

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

Поделиться:
Популярные книги

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Мастер 6

Чащин Валерий
6. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 6

Кодекс Охотника. Книга IV

Винокуров Юрий
4. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга IV

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Барон диктует правила

Ренгач Евгений
4. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон диктует правила

На изломе чувств

Юнина Наталья
Любовные романы:
современные любовные романы
6.83
рейтинг книги
На изломе чувств

Охота на эмиссара

Катрин Селина
1. Федерация Объединённых Миров
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Охота на эмиссара

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Король Масок. Том 1

Романовский Борис Владимирович
1. Апофеоз Короля
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Король Масок. Том 1

Релокант

Ascold Flow
1. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант

Адмирал южных морей

Каменистый Артем
4. Девятый
Фантастика:
фэнтези
8.96
рейтинг книги
Адмирал южных морей

Возвышение Меркурия. Книга 17

Кронос Александр
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 17