Учебник Информатика. Базовый курс. Симонович С.В.. С. В. Симоновичаинформатикабазовый курс2е издание
Скачать 17.96 Mb.
|
Синтаксис оператора цикла Бейсик DO WHILE условие группа операторов LOOP Паскаль while условие do оператор или группа Си++ while( условие ) оператор или группа операторов; Бейсик: DO WHILE A > В А = А - 0.01 LOOP Паскаль: while a > b do а := а - 0.01; Си++: while ( а > b ) а а - 0.01; Зацикливание При использовании условных операторов цикла программиста подстерегает одна опасность. Как показывает практика, достаточно легко сделать ошибку и неверно задать условие окончания цикла, которое всегда будет истинным, — при этом тело цикла станет выполняться бесконечно. Подобная ситуация называется зациклива- нием. Например: а = 0; b 1; a < b ) а = а - 0 . ; Так как исходное значение переменной а меньше, чем значение переменной и это значение будет только уменьшаться, то подобный цикл никогда не закончится. В некоторых случаях программисты специально применяют подобный трюк, чтобы организовать бесконечный цикл, в котором будут приниматься и обрабатываться 5 9 8 Глава 20. Основы программирования внешние сообщения (события). Тогда использование условного оператора цикла может выглядеть так: while t r u e do begin // тело цикла end; Контроль над выходом из цикла при наступлении определенного события при этом полностью возлагается на программиста. В Бейсике есть специальная форма оператора цикла, позволяющая явно описы- вать такие бесконечные циклы: DO ' тело цикла LOOP Исключения Управление порядком выполнения программы может происходить только с помощью условных операторов и операторов цикла, но и при возникновении исклю- чений — ситуаций в программе или операционной системе, требующих немедлен- ного реагирования. Например, при выполнении оператора присваивания и вычис- лении выражения произошло деление на ноль. Программа остановилась, так как не знает, что ей делать дальше, — ведь получено ошибочное Чаще всего выполнение программы просто прекращается по ошибке, но современные системы разработки позволяют программисту явно контролировать возникновение самых разных исключений (они еще называются исключительными ситуациями, требу- ющими немедленного вмешательства) и указывать, какие операторы следует выпол- нять при их возникновении. Параллельные вычисления Еще одна область программирования, в которой возможно изменение явно указан- ного порядка выполнения операторов, — это область параллельных вычислений. С появлением недорогих ПК с несколькими процессорами возникла возможность распараллеливания программы — одновременного выполнения ее независимых частей на разных процессорах, что теоретически позволяет получить выигрыш в быстродействии, линейно зависящий от числа процессоров. Однако на практике это очень сложная задача, которая требует правильного выделения независимых модулей кода (так называемых процессов), выполнение которых не скажется на результатах работы других процессов. Так как момент окончания работы того или иного процесса заранее неизвестен, то в программе надо предусмотреть действия, связанные с синхронизацией обработки получаемых результатов. Их выполнение может потребоваться в самые неожиданные моменты, поэтому изменение линей- ной последовательности работы операторов неизбежно. 20.4. Структурное программирование 5 9 9 и Чтобы получать от человека информацию для обработки и показывать результаты своей работы, программа должна иметь средства для организации интерактивного общения с пользователем (общения в реальном масштабе времени — человек щелк- нул мышкой на кнопке и сразу получил ответ) и средства для ввода данных из файлов и сохранения данных в файлах. общение реализуется с помощью позволяющих быстро спроектировать пользовательский интерфейс. Ввод и вывод информации осуществляется в разных языках по-разному. В Паскале и есть операторы для такой работы, в Си++ они выделены в специальные библиотеки. Введен также специальный тип данных «файл» (FILE). Работа с файлами всегда происходит в три этапа. 1. Файл открывается в одном из выбранных режимов (он рассматривается как последовательность строк или двоичных чисел, разрешается только считывать из него данные или только записывать и т. д.). Файл может состоять из последо- вательности одинаковых блоков, каждый из которых будет представлять собой копию структуры данных определенного типа, описанного в программе. Каждый такой блок называется записью. 2. Выполняется считывание, обновление или удаление записей в 3. Файл закрывается. Если этого не сделать, то он останется открытым и в даль- нейшем к нему нельзя будет обратиться из других программ. Каждый из этих пунктов реализуется в каждом из языков программирования по- своему. Некоторые пункты требуют для своей реализации нескольких операторов. Вопросы для самоконтроля 1. Какие типы данных считаются базовыми? 2. Приведите примеры арифметических и логических выражений. 3. Напишите формулу для вычисления среднего арифметического и среднего гео- метрического значений двух переменных. 4. В чем различие структуры и массива? 5. Зачем нужны комментарии? 6. С помощью условных операторов проверку х < у < z. 7. Из каких частей состоит оператор цикла? 8. Назовите достоинства и недостатки параллельных вычислений. 9. Как организуется работа с файлами? 20.4. Структурное программирование Подпрограммы В предыдущем разделе рассматривались основные операторы и типы данных, необ- ходимые для составления программ. При этом предполагалось, что текст программы 6 0 0 Глава 20. Основы программирования представляет собой линейную последовательность операторов присваивания, цикла и условных операторов. Таким способом можно решать не очень сложные задачи и составлять программы, содержащие несколько сот строк кода. После этого понятность исходного текста резко падает из-за того, что общая структура алго- ритма теряется за конкретными операторами языка, выполняющими слишком детальные, элементарные действия. Возникают многочисленные вложенные услов- ные операторы и операторы циклов, логика становится совсем запутанной, при попытке исправить один ошибочный оператор вносится несколько новых ошибок, связанных с особенностями работы этого оператора, результаты выполнения кото- рого нередко учитываются в самых разных местах программы. Поэтому набрать и отладить длинную линейную последовательность операторов практически невоз- можно. При создании средних по размеру приложений (несколько тысяч строк исходного кода) используется структурное программирование, идея которого заключается в том, что структура программы должна отражать структуру решаемой задачи, чтобы алгоритм решения был ясно виден из исходного текста. Для этого надо иметь сред- ства для создания программы не только с помощью трех простых операторов, но и с помощью средств, более точно отражающих конкретную структуру алгоритма. С этой целью в программирование введено подпрограммы — набора операторов, выполняющих нужное действие и не зависящих от других частей исходного кода. Программа разбивается на множество мелких подпрограмм (занимающих до 50 операторов — критический порог для быстрого понимания цели подпрограммы), каждая из которых выполняет одно из действий, предусмотренных исходным зада- нием. Комбинируя эти подпрограммы, удается формировать итоговый алгоритм уже не из простых операторов, а из законченных блоков кода, имеющих опреде- ленную смысловую нагрузку, причем обращаться к таким блокам можно по назва- ниям. Получается, что подпрограммы — это новые операторы или операции языка, определяемые программистом. Возможность применения подпрограмм относит язык программирования к классу процедурных языков. Нисходящее проектирование Наличие подпрограмм позволяет вести проектирование и разработку приложения сверху вниз — такой подход называется нисходящим проектированием. Сначала выделяется несколько подпрограмм, решающих самые глобальные задачи (напри- мер, инициализация данных, главная часть и завершение), потом каждый из этих модулей детализируется на более низком уровне, разбиваясь в свою очередь на небольшое число других подпрограмм, и так происходит до тех пор, пока вся задача не окажется реализованной. Такой подход удобен тем, что позволяет человеку постоянно мыслить на предмет- ном уровне, не опускаясь до конкретных операторов и Кроме того, появляется возможность некоторые подпрограммы не реализовывать сразу, а вре- менно откладывать, пока не будут закончены другие части. Например, если имеется необходимость вычисления сложной математической функции, то выделяется 20.4. Структурное программирование 601 отдельная подпрограмма такого вычисления, но реализуется она временно одним оператором, который просто присваивает заранее выбранное значение (например, 5). Когда все приложение будет написано и отлажено, тогда можно приступить к реа- лизации этой функции. Немаловажно, что небольшие подпрограммы значительно проще отлаживать, что существенно повышает общую надежность всей программы. Очень важная характеристика подпрограмм — это возможность их повторного использования. С интегрированными системами программирования поставляются большие библиотеки стандартных подпрограмм, которые позволяют значительно повысить производительность труда за счет использования чужой работы по созда- нию часто применяемых подпрограмм. Рассмотрим пример, демонстрирующий методику нисходящего проектирования. Имеется массив Ocenki, состоящий из N (N> 2) судейских оценок (каждая оценка положительна). В некоторых видах спорта принято отбрасывать самую большую и самую маленькую оценки, чтобы избежать влияния необъективного судейства, а в зачет спортсмену идет среднее арифметическое из оставшихся оценок. Решим эту задачу, постепенно детализируя алгоритм (без привязки к конкретному языку программирования). 1. Процесс решения наиболее просто описывается подпрограммами: Теперь можно приступить к детализации каждой их этих подпрограмм. 2. Удалить_самую_большую_оценку; Как удалить самую большую оценку из статического массива? Вместо нее можно просто записать значение 0, а при подсчете среднего арифметического нуле- вые значения не учитывать. I = I ] = 0; 3. Удалить_самую_маленькую_оценку; I I ) = 0; При реализации подпрограммы Номер_самого_маленького_элемента_в_массиве надо учесть, что искать придется самое маленькое из положительных значе- ний (больших нуля). 4. Рассчитать_среднее_арифметическое_оставшихся_оценок; 6 0 2 Глава 20. Основы программирования Здесь потребуется оператор цикла, вычисляющий сумму всех элементов мас- сива = 0 FOR I = 1 N SUM = SUM + I ) NEXT SUM = SUM / (N - 2) В последнем операторе происходит вычисление среднего арифметического всех оценок. Сумма элементов массива делится на число элементов, уменьшенное на 2, потому что две оценки, самую большую и самую маленькую, учитывать не надо. Если бы эта задача решалась последовательно, то уже на этапе удаления оценок могли возникнуть определенные проблемы. Реализацию подпрограмм Номер_ выполните самостоятельно. Процедуры и функции Подпрограммы бывают двух видов — процедуры и функции. Отличаются они тем, что процедура просто выполняет группу операторов, а функция вдобавок вычис- ляет некоторое значение и передает его обратно в главную программу (возвращает значение). Это значение имеет определенный тип (говорят, что функция имеет такой-то тип). В Си++ понятия «процедура» нет — там имеются только функции, а если никакого значения функция не вычисляет, то считается, что она возвращает значение типа «никакое» (void). Параметры подпрограмм Чтобы работа подпрограммы имела смысл, ей надо получить данные из внешней которая эту подпрограмму вызывает. Данные передаются подпрограмме в виде параметров или аргументов, которые обычно описываются в ее заголовке так же, как переменные. Управление последовательностью вызова подпрограмм Подпрограммы вызываются, как правило, путем простой записи их названия с нужными параметрами. В Бейсике есть оператор CALL для явного указания того, что происходит вызов подпрограммы. Подпрограммы активизируются только в момент их вызова. Операторы, находя- щиеся внутри подпрограммы, выполняются, только если эта подпрограмма явно вызвана. Пока выполнение подпрограммы полностью не закончится, оператор глав- ной программы, следующий за командой вызова подпрограммы, выполняться не будет. 20.4. Структурное программирование Подпрограммы могут быть вложенными — допускается вызов подпрограммы не только из главной программы, но и из любых других подпрограмм. В некоторых языках программирования допускается вызов подпрограммы из себя самой. Такой прием называется рекурсией и потенциально опасен тем, что может привести к зацикливанию — бесконечному самовызову. Структура подпрограммы Подпрограмма состоит из нескольких частей: заголовка с параметрами, тела под- программы (операторов, которые будут выполняться при ее вызове) и завершения подпрограммы. Локальные переменные, объявленные внутри подпрограммы, имеют областью дей- ствия только ее тело. Заголовок функции Тело Завершение Бейсик FUNCTION имя (список_параметров) Тип возвращаемого значения определяется специальным символом после имени функции Последовательность операторов END FUNCTION Паскаль function имя (список_параметров): тип_функции; begin последовательность операторов end; нет Си++ тип функции { последовательность операторов }; нет Как функция возвращает значение После того как функция рассчитала нужное значение, ей требуется явно вернуть его в вызывающую программу. Для этого может использоваться специальный опе- ратор (return в Си++) или особая форма оператора присваивания, когда в левой части указывается имя функции, а справа — возвращаемое значение. 604 ' Глава 20. Основы программирования Далее приведены примеры функции, вычисляющей значение квадрата аргумента. Бейсик: FUNCTION SQR% (X AS INTEGER) SQR% = X*X END FUNCTION Паскаль: function SQR(X: i n t e g e r ) : integer; begin SQR := X*X end; Си++: i n t SQR(int x) { return x*x; } ; Формальные и фактические параметры Во время создания подпрограммы заранее не известно, какие конкретно параметры она может и будет получать. Поэтому в качестве переменных, выступающих в роли ее аргументов в заголовке, могут использоваться произвольные допустимые назва- ния, даже совпадающие с уже имеющимися. Компилятор все равно поймет, что это не одно и то же. Параметры, которые указываются в заголовке подпрограммы, называются фор- мальными. Они нужны только для описания тела подпрограммы. А параметры (кон- кретные значения), которые указываются в момент вызова подпрограммы, назы- ваются фактическими параметрами. При выполнении операторов подпрограммы формальные параметры как бы временно заменятся на фактические. Пример. i n t а, у; а у = SQR(a); Программа вызывает функцию SQR() с одним фактическим параметром а. Внутри подпрограммы формальный параметр х получает значение переменной а и возво- дится в квадрат. Результат возвращается обратно в программу и присваивается переменной у. Событийно-ориентированное программирование С активным распространением системы Windows и появлением визуальных RAD- сред широкую популярность приобрел событийный подход к созданию программ — событийно-ориентированное программирование. 20.5. Объектно-ориентированное программирование 6 0 5 Идеология системы Windows основана на событиях. Щелкнул человек на кнопке, выбрал пункт меню, нажал на клавишу или кнопку мыши — в Windows генериру- ется подходящее сообщение, которое отсылается окну соответствующей программы. Структура программы, созданной с помощью событийного программирования, следующая. Главная часть представляет собой один бесконечный цикл, который опрашивает Windows, следя тем, не появилось ли новое сообщение. При его обна- ружении вызывается подпрограмма, ответственная за обработку соответствующего события (обрабатываются не все события, их сотни, а только нужные), и подобный цикл опроса продолжается, пока не будет получено сообщение «Завершить работу». События могут быть пользовательскими, возникшими в результате действий поль- зователя, системными, возникающими в операционной системе (например, сообще- ния от таймера), и программными, генерируемыми самой программой (например, обнаружена ошибка и ее надо обработать). Событийное программирование является развитием идей нисходящего проекти- рования, когда постепенно определяются и детализируются реакции программы на различные события. Вопросы для самоконтроля 1. С какой целью применяют подпрограммы? 2. Чем характеризуются процедурные языки программирования? 3. В чем состоит идея нисходящего проектирования? 4. Что общего и в чем отличия процедуры и функции? 5. Определите значение выражения F(1,2) + 10,0.1), если функция рас- считывается как а*а + b*b. 6. В чем различие между событийным и структурным программированием? 7. Как организуется обработка программных событий? Объектно-ориентированное программирование Понятие объекта Развитие идей структурного и событийного программирования существенно под- няло производительность труда программистов и позволило в разумные сроки (несколько месяцев) создавать приложения объемом в сотни тысяч строк. Однако такой объем уже приблизился к пределу возможностей человека, и потребовались новые технологии разработки программ. В начале 80-х годов в программировании возникло новое направление, основанное на понятии объекта. До того времени основные ограничения на возможность созда- ния больших систем накладывала разобщенность в программе данных и методов их обработки. Реальные объекты окружающего мира обладают тремя базовыми характеристиками: они имеют набор свойств, способны разными методами изменять эти свойства и реагировать на события, возникающие как в окружающем мире, так и внутри самого |