Этапы разработки программы
Тема:Алгоритм и его свойства. Запись алгоритмов. Виды алгоритмов
Цель урока:
- Дать понятие алгоритму и его свойствам. Проверить знания прошлого урока.
- Воспитание умения слушать учителя.
- Развитие познавательного интереса.
План урока:
- Постановка цели урока.
- Проверка домашнего задания.
- Объяснение нового материала.
- Примеры алгоритмов.
- Домашняя работа.
- Подведение итогов урока.
В 1983 году отмечалось 1200-летие со дня рождения величайшего средневекового ученого Средней Азии Мухамеда ибн Мусы аль-Хорезми. С именем этого ученого связано понятие алгоритма. Итак, Алгоритм - это определённая последовательность действий, которые необходимо выполнить, чтобы получить результат. Алгоритм может представлять собой некоторую последовательность вычислений, а может - последовательность действий нематематического характера. Для любого алгоритма справедливы общие закономерности - свойства алгоритма.
Свойства алгоритма.
- Дискретность.
- Понятность
- Детерминированность
- Массовость
- Результативность
Дискретность - это свойство алгоритма, когда алгоритм разбивается на конечное число элементарных действий (шагов).
Понятность - свойство алгоритма, при котором каждое из этих элементарных действий (шагов) являются законченными и понятными.
Детерминированность - свойство, когда каждое действие (операция.указание.шаг.требование) должно пониматься в строго определённом смысле, чтобы не оставалась места произвольному толкованию. чтобы каждый, прочитавший указание, понимал его однозначно.
Массовость - свойство, когда по данному алгоритму должна решаться не одна, а целый класс подобных задач.
Результативность – свойство, при котором любой алгоритм в процессе выполнения должен приводить к определённому результату. Отрицательный результат также является результатом.
Алгоритм может быть записан различными способами: на естественном языке в виде описания; в виде графических блок-схем; на специальном алгоритмическом языке.В школе на уроках информатики для записи алгоритмов используется, так называемый, "школьный алгоритмический язык". Этот язык по существу является "мёртвым" языком,. так как на нём не работают компьютеры, и мы не будем им пользоваться. Запись алгоритмов на родном языке доступна и удобна. Примеров таких записей множество, хотя бы книга кулинарных рецептов есть не что иное, как сборник алгоритмов, написанных на родном языке.
Существенным недостатком такой записи является недостаточная наглядность, что особенно сказывается, когда алгоритм имеет много ветвлений. Поэтому, мы будем записывать наши алгоритмы в виде блок-схемы.
Основные блоки алгоритмов.
Все имеющиеся алгоритмы можно разделить на три вида:
- линейные алгоритмы;
- алгоритмы ветвления;
- циклические алгоритмы.
Этапы разработки программы
Выражение "написать программу" отражает только один из этапов создания компьютерной программы, когда разработчик программы (программист) действительно пишет команды (инструкции) на бумаге или при помощи текстового редактора.
Программирование — это процесс создания (разработки) программы, который может быть представлен последовательностью следующих шагов:
1. Спецификация (определение, формулирование требований к программе).
2. Разработка алгоритма.
3. Кодирование (запись алгоритма на языке программирования).
4. Отладка.
5. Тестирование.
6. Создание справочной системы.
7. Создание установочного диска (CD-ROM).
Жизненный цикл ПО
Из каких этапов складывается процесс создания и использования ПО?
Программное обеспечение, независимо от его размеров и сложности, имеет жизненный цикл, в
котором выделяют следующие этапы:
1. Этап разработки технического задания (постановка задачи) На этом этапе формулируется желание заказчика в виде документа (ТЗ), содержащего описание цели разработки, исходных данных, результатов работы, требований к специальному программному обеспечению, аппаратным средствам, функциональным возможностям. Поскольку программист редко досконально разбирается в предметной области, а заказчик - в программировании, постановка задачи может стать весьма непростым итерационным процессом. Для этапа ТЗ очень важно ясно определить входные данные программы и результат ее работы.
2. Этап проектирования Проектирование можно разбить на более мелкие этапы:
• анализ технического задания;
• определение структур данных;
• разработка или адаптация алгоритмов обработки данных;
• структурная декомпозиция (разбиение исходной задачи на относительно независимые мелкие подзадачи);
• описание программы в виде схем, блок-схем или другим способом;
• выбор языка программирования (или нескольких языков) для достижения наилучших
результатов;
На этапе проектирования следует учитывать возможность будущих модификаций программы и
стремиться к тому, чтобы вносить эти изменения было бы просто.
3. Этап кодирования Реализация структурной схемы программы на выбранном языке
программирования и получение исполняемых модулей.
4. Этап отладки Испытание программы с целью проверки функциональных возможностей, надежности
работы поиска ошибок проектирования и кодирования. При необходимости вносятся изменения в
проект и исходный код.
5. Этап сдачи заказчику в эксплуатацию и сопровождение После получения исполняемых модулей и успешного тестирования программа передается заказчику для эксплуатации, в сопровождении с комплектом необходимой документации. Сопровождение программы заключается в устранении выявленных в течении работы ошибок (пропущенных на этапе отладки), своевременном их устранении и выпуске новых версий. Необходимо сделать несколько замечаний в связи с процессом разработки и сопровождения ПО. Наиболее распространенной ошибкой программистов является пренебрежение этапами технического
задания и проектирования. В этом случае программа сразу начинает кодироваться, а все исправления вносятся прямо по ходу кодирования. Такой подход совершенно неприемлем при разработке больших программ, так как ведет к потерям времени на многочисленные исправления, чреват многочисленными ошибками в программе. И совершенно невозможно в таком случае организовать деятельность коллектива программистов, работающих над одним проектом. Кроме того, разработка структуры программы должно предшествовать процессу написания исходного кода. Тогда процесс кодирования будет непродолжительным, а текcт программы - эффективным. Распространенной ошибкой является нерациональное тестирование программы, обусловленное плохим знанием ее слабых мест. Очевидно, что в первую очередь необходимо обратить внимание на те места, которые могут стать причиной программных и аппаратных сбоев (возможное деление на ноль, обращение к дисководу без дискеты и т.д.) Недопустимо выпускать программу без документации (пусть даже в виде одной страницы текста), с непонятным и недружественным пользователю интерфейсом. Интерфейс, или процесс взаимодействия программы с пользователем должен соответствовать международным стандартам и быть легко осваиваемым. И, наконец, несколько слов об оформлении исходного кода программы. Для того, чтобы работать в коллективе, необходимо уважать своих коллег, которые имеют отношение к разрабатываемой программе (неважно, работаете вы одновременно, или с разницей во времени). Очень часто программы пишутся как бы “для себя“ и об оформлении исходного кода не особенно заботятся. Это может сослужить плохую службу разработчику, так как способствует его дурной славе, делает текст программы недоступной как для собственного, так и для чужого понимания, мешает повторному его (текста) использованию.
1.6. Восходящее и нисходящее проектирование ПО
Существуют два основных вида проектирования программ - нисходящее (“сверху-вниз“ - ВН) и восходящее (“снизу-вверх“ - НВ). Суть восходящей технологии заключается в том, что сначала решаются более частные и понятные задачи (реализация алгоритма сортировки, обработка строки, ввод данных) и только потом приступают к построению большой программы из готовых мелких частей. Можно сказать, что суть НВ - “ОТ
ЧАСТНОГО К ОБЩЕМУ“. Нисходящая технология состоит в первоначальной разработке скелета программы, определению процедур и связей между ними, и лишь потом проектировщик определяет содержимое процедур и структур данных. В этом случае активно используются т.н. “заглушки“ - процедуры-пустышки, не выполняющие пока никакой полезной работы, но имеющие заголовок с параметрами и использующиеся
для предварительной отладки программы. В основном, программы создаются с использованием смешанных технологий, то есть на разных участках могут использоваться как НВ, так и ВН. В процессе проектирования активно используется модель “черного ящика“, в которой процедура или участок программы представляются блоком, имеющим несколько входов и выходов, внутренняя структура которого несущественна на данном этапе проектирования.
На этом шаге мы рассмотрим методы восходящего и нисходящего проектирования.
Другой метод улучшения качества программирования заключается в применении нисходящего проектирования (Top-Down Programming - программирование "сверху вниз").
В методе нисходящего проектирования Вы вначале пишете основную программу, используя средства вызова подпрограмм, причем в качестве подпрограмм вначале Вы вводите "заглушки" вида:
Вызвали подпрограмму номер ... .
Затем, будучи уверенным в правильности логического построения основной программы, Вы детально "расписываете" каждую подпрограмму, вызывая по мере необходимости подпрограммы более низкого уровня. Этот последовательный процесс продолжается, пока программа не будет завершена и проверена.
При другом методе - восходящем проектировании (программировании "снизу вверх") - Вы вначале пишете подпрограммы нижнего уровня и тщательно их тестируете и отлаживаете. Далее Вы добавляете подпрограммы более высокого уровня, которые вызывают подпрограммы нижнего уровня, и так до тех пор, пока Вы не достигнете программы самого верхнего уровня. Метод проектирования "снизу вверх" пригоден при наличии больших библиотек стандартных подпрограмм.
Учтите, что иногда лучшим является гибрид двух методов. Однако в обоих случаях каждая подпрограмма должна быть небольшой, так чтобы можно было охватить одним взглядом всю ее логику (для персональных компьютеров желательно, чтобы и основная программа, и подпрограммы целиком помещались в пределах 20-30 строк экрана дисплея!)
Всякий велосипедист хорошо знает, что ехать сверху вниз быстрее и удобнее, чем снизу вверх. В программировании дело обстоит примерно так же: "сверху вниз" писать программы удобнее потому, что при таком методе мы точно знаем, какие подпрограммы описывать.
Но есть у этого метода и недостаток: на верхнем уровне не всегда видно, куда спускаться, то есть как разделить решение задачи на такие части, каждую из которых было бы легко описать отдельной процедурой. У опытных программистов вырабатывается своеобразное чутье: они сразу видят, какие нужны процедуры, а новичкам иногда приходится туго.
Метод "снизу вверх", хотя и требует большого труда, бывает очень полезен на первых порах. Пусть даже половину составленных Вами подпрограмм придется потом "выбросить", но зато Вы хорошо почувствуете, какие подпрограммы для исходной задачи необходимы. Да и отлаживать каждую написанную подпрограмму можно сразу: ведь все, что "под ней", уже описано (а обычно и отлажено). Словом, любишь кататься "сверху вниз" - люби и саночки возить (в обратном направлении). Опытные программисты иногда применяют метод "снизу вверх" для того, чтобы заранее заготовить для новой задачи набор подпрограмм, которые могут понадобиться в различных случаях. Так что "возить саночки" приходится не только новичкам!
Для оценки упомянутой производительности используется ряд критериев качества программ. Поскольку такое комплексное понятие производительности формально определить невозможно, критерии также оказываются не строго определенными, взаимосвязанными, а иногда противоречивыми. В разных источниках могут приводиться различные наборы критериев. Но, несмотря на это, как правило эти наборы сводимы один к другому и хорошо работают!
Автор предлагает следующую совокупность критериев.
1. Работоспособность.
2. Правильность.(программа должна решать именно поставленную, а не более широкую, более узкую или измененную задачу).
3. Надежность (программа должна работать при любых исходных данных – анализировать их правильность и выдавать результаты или диагностику ошибок).
4. Читабельность (текст программы – итоговый носитель всей информации о решении, поэтому он должен иметь четкую и ясную организацию, отображающую решение).
5. Легкость отладки и тестирования.
6. Модифицируемость (возможность внесения изменений в программу).
7. Документированность (наличие документации по всему процессу разработки, начиная от постановки задачи); документированность обеспечивает возможность передачи программы другим лицам, или отчуждение программы.
8. Простота пользования, наличие сервиса.
9. эффективность применительно к компьютеру (использование минимума машинных ресурсов – памяти и времени выполнения).
Видно, например, что критерии 4, 6, 7 взаимосвязаны, критерий 5 ими определяется; критерии 3 – 8 противоречат 9-му, и сам он внутренне противоречив. Делать акцент на тех или иных критериях следует в зависимости от реальной ситуации. Так, мощность современных компьютеров в большинстве случаев позволяет не слишком учитывать ресурсы. Однако если речь идет о специальных расчетных инженерных задачах, время решения которых объективно велико, на первый план выступают ресурсы.
Цикл. Виды Циклов. Циклом называется многократное повторение однотипных действий. Телом же цикла будем называть те самые действия, которые нужно многократно повторять. Как вы понимаете, повторять одни и те же действия можно и при помощи оператора безусловного перехода. Если записать эти действия в программе одно за другим, а в конце поставить оператор перехода к началу этого блока. Однако таким образом можно получить только программу, которая работает вечно (зацикливается). Этого можно избежать, используя совместно с оператором перехода условный оператор, поставив выполнение перехода в зависимость от выполнения некого условия. Таким образом, мы получим структуру условного перехода и возможность организации конечного цикла. Вообще говоря, так мы можем решить практически любую задачу, требующую реализации циклического алгоритма. Конечно же, при помощи одного только топора можно построить дом. Поставим перед собой вопросы: "А будет ли этот дом красив? Сколько времени и сил можно сэкономить, используя всевозможные специальные инструменты?". Создатель языка Паскаль Никлаус Вирт также задался этими вопросами и решил их в пользу расширения языка тремя специальными возможностями организации циклов. Для чего? - Для удобства, краткости, простоты чтения программы и, не побоюсь этого слова, красоты. Итак, существует три вида цикла, имеющих собственные операторы на языке Паскаль для их записи. Эти виды имеют собственные условные названия: "Пока", "До", "С параметром". Друг от друга они несколько отличаются и используются каждый для своего класса задач. Цикл "ПОКА" Группа операторов, называемая "телом цикла", судя по этой схеме, будет выполняться пока истинно условие цикла. Выход из цикла произойдет, когда условие перестанет выполняться. Если условие ложно изначально, то тело цикла не будет выполнено ни разу. Если условие изначально истинно и в теле цикла нет действий, влияющих на истинность этого условия, то тело цикла будет выполняться бесконечное количество раз. Такая ситуация называется "зацикливанием". Прервать зациклившуюся программу может либо оператор (нажав Ctrl+C), либо аварийный останов самой программы, в случае переполнения переменной, деления на ноль и т.п., поэтому использовать структуру цикла следует с осторожностью, хорошо понимая, что многократное выполнение должно когда-нибудь заканчиваться. На языке Pascal структура цикла "Пока" записывается следующим образом: While <условие> Do <оператор>; Правда, лаконично? По-русски можно прочитать так: "Пока истинно условие, выполнять оператор". Здесь, так же как в формате условного оператора, подразумевается выполнение только одного оператора. Если необходимо выполнить несколько действий, то может быть использован составной оператор. Тогда формат оператора принимает такой вид: While <условие> DoBegin <оператор #1>;<оператор #2>;<оператор #3>; . . . End; Цикл "ДО" Этот вид цикла отличается от предыдущего в основном тем, что проверка условия повторения тела цикла находится не перед ним, а после. Поэтому цикл "До" называют циклом "с постусловием", а "Пока" - "с предусловием". Обратите также внимание на то, что новая итерация (повторное выполнение тела цикла) происходит не тогда, когда условие справедливо, а как раз тогда, когда оно ложно. Поэтому цикл и получил свое название (выполнять тело цикла до выполнения соответствующего условия). Интересно, что в случае, когда условие цикла изначально истинно, тело цикла все равно будет выполнено хотя бы один раз. Именно это отличие "до" от "пока" привело к тому, что в программировании они не подменяют друг друга, а используются для решения задач, к которым они более подходят. Формат цикла на языке Pascal:Repeat<оператор #1>; <оператор #2>; <оператор #3>;. . . Until <условие>; Читается так: "Выполнять оператор #1, оператор #2. : до выполнения условия". Здесь не требуется использование составного оператора, потому, что сами слова Repeat и Until являются операторными скобками. Цикл "С параметром". В данном случае параметром будет являться целочисленная переменная, которая будет изменяться на единицу при каждой итерации цикла. Таким образом, задав начальное и конечное значения для такой переменной, можно точно установить количество выполнений тела цикла. Нарисовать блок-схему такой структуры вы сможете сами после некоторых пояснений. Форматов у этого вида цикла предусмотрено два: For <И.П.>:=<Н.З.> To <К.З.> Do <оператор>; For <И.П.>:=<Н.З.> Downto <К.З.> Do <оператор>; Здесь И.П. - имя переменной-параметра, Н.З. - его начальное значение,К.З. - соответственно конечное значение параметра. В качестве начального и конечного значений Читается данная структура так: "Для переменной (далее следует ее имя) от начального значения до конечного выполнять оператор (являющийся телом цикла)". Иногда цикл с параметром даже называют "Для" или "For". В первом случае параметр с каждой итерацией увеличивается на единицу, во втором - уменьшается. Выполняется этот цикл по следующему алгоритму:1. переменной-параметру присваивается начальное значение;2. выполняется тело цикла;3. переменная-параметр автоматически увеличивается на 1 (в первом случае формата); 4. если параметр превышает конечное значение, то происходит выход из цикла, иначе - переход к пункту 2. Примечание: при использовании Downto параметр автоматически уменьшается на 1, а выход из цикла происходит тогда, когда параметр становится меньше конечного значения. Таким образом, в отличие от первых двух видов цикла, этот цикл используется тогда, когда известно необходимое количество выполнений тела цикла. | Вообще говоря, цикл "Пока" является универсальным, то есть любая задача, требующая использования цикла, может быть решена с применением этой структуры. Циклы "До" и "С параметром" созданы для удобства программирования.Итерационный цикл - оператор цикла, для которого число повторений тела цикла заранее неизвестно. В итерационных циклах на каждом шаге вычислений происходит последовательное приближение и проверка…
В итерационных циклах производится проверка некоторого условия, и в зависимости от результата этой проверки происходит либо выход из цикла, либо повторение выполнения тела цикла. Если проверка условия производится перед выполнением блока операторов, то такой итерационный цикл называется циклом с предусловием (цикл "пока"), а если проверка производится после выполнения тела цикла, то это цикл с постусловием (цикл "до").
Особенность этих циклов заключается в том, что тело цикла с постусловием всегда выполняется хотя бы один раз, а тело цикла с предусловием может ни разу не выполниться. В зависимости от решаемой задачи необходимо использовать тот или иной вид итерационных циклов.
Параметрический цикл For… Next
Этот цикл управляется параметром, который при повторении выполнения тела цикла изменяет с заданным шагом свое значение от заданного начального значения до заданного конечного значения. Такой цикл используют в случае, когда заранее известно, сколько необходимо совершить повторений выполнения тела.
Синтаксис цикла:
ForИПЦ=НЗПЦToКЗПЦ[StepШИПЦ] Тело цикла (одна или несколько инструкций)
Next [ИПЦ]
Слова For (для), To (до), Step (шаг), Next (затем) являются зарезервированными.
Применены обозначения:
· ИПЦ – имя параметра цикла (переменная любого числового типа);
· НЗПЦ – начальное значение параметра цикла (выражение любого числового типа), которое параметр цикла будет иметь при первом выполнении тела цикла;
· КЗПЦ – конечное значение параметра цикла (выражение любого числового типа), с которым сравнивается текущее значение параметра цикла;
· ШИПЦ – шаг изменения параметра цикла (выражение любого числового типа) – необязательная часть инструкции цикла.
Числовые значения НЗПЦ и КЗПЦ задают интервал, в котором будет изменяться параметр цикла. Необязательный параметр ШИПЦ задает шаг изменения счетчика цикла на каждом проходе. По умолчанию, если он отсутствует, то принимается равным 1. Наконец, после инструкций, составляющих тело цикла, следует команда, обозначающая границу действия цикла. В случае вложенных циклов (в тело цикла входит инструкция цикла) полезно указывать, к какому из них относится команда Next. Это достигается добавлением после слова Next имени параметра цикла.
Процесс выполнения инструкции For… Next для положительного шага иллюстрирует рисунок 4.
Операторы ветвления
К операторам, позволяющим из нескольких возможных вариантов выполнения программы (ветвей) выбрать только один, относятся if и case.
Условный оператор if
Оператор if выбирает между двумя вариантами развития событий:
if <условие> then <один_оператор> [else <один_оператор>];Обратите внимание, что перед словом else (когда оно присутствует, конечно же) символ ";" не ставится - ведь это разорвало бы оператор на две части.
Условный оператор if работает следующим образом:
- Сначала вычисляется значение <условия> - это может быть любое выражение, возвращающее значение типа boolean.
- Затем, если в результате получена "истина" (true), то выполняется оператор, стоящий после ключевого слова then, а если "ложь" (false) - без дополнительных проверок выполняется оператор, стоящий после ключевого слова else. Если же else-ветвь отсутствует, то не выполняется ничего.
Что же произойдет, если написать несколько вложенных операторов if?
В случае, когда каждый оператор if имеет собственную else-ветвь, все будет в порядке. А вот если некоторые из них этой ветви не имеют, может возникнуть ошибка. Компилятор языка Pascal всегда считает, что else относится к самому ближнему оператору if. Таким образом, если написать
if i>0 then if s>2 then s:= 1 else s:= -1;подразумевая, что else-ветвь относится к внешнему оператору if, то компилятор все равно воспримет эту запись как
if i>0 then if s>2 then s:= 1 else s:= -1 else;Ясно, что таким образом правильного результата получить не удастся.
Для того чтобы избежать подобных ошибок, стоит всегда (или по крайней мере при наличии нескольких вложенных условных операторов) указывать оба ключевых слова, даже если одна из ветвей будет пустовать. Так вы застрахуетесь от одной из частых "ошибок по невнимательности", которые очень сложно найти в процессе отладки программы.
Итак, исходный вариант нужно переписать следующим образом:
if i>0 then if s>2 then s:=1 else else s:=-1;либо так:
if i>0 then begin if s>2 then s:=1 end else s:=-1;Вообще же, если есть возможность переписать несколько вложенных условных операторов как один оператор выбора, это стоит сделать.
Оператор выбора case
Оператор case позволяет сделать выбор между несколькими вариантами:
case <переключатель> of <список_констант> : <один_оператор>; [<список_констант> : <один_оператор>;] [<список_констант> : <один_оператор>;] [else <один_оператор>;]end;Замечание: Обратите внимание, что после else двоеточие не ставится.
Существуют дополнительные правила, относящиеся к структуре этого оператора:
- Переключатель должен относиться только к порядковому типу данных, но не к типу longint.
- Переключатель может быть переменной или выражением.
- Список констант может задаваться как явным перечислением, так и интервалом или их объединением.
- Повторение констант не допускается.
- Тип переключателя и типы всех констант должны быть совместимыми1).
Пример оператора выбора:
case symbol(* :char *) of 'a'..'z', 'A'..'Z' : writeln('Это латинская буква'); 'а'..'я', 'А'..'Я' : writeln('Это русская буква'); '0'..'9' : writeln('Это цифра'); ' ',#10,#13,#26 : writeln('Это пробельный символ'); else writeln('Это служебный символ');end;Выполнение оператора case происходит следующим образом:
- вычисляется значение переключателя;
- полученный результат проверяется на принадлежность к тому или иному списку констант;
- если такой список найден, то дальнейшие проверки уже не производятся, а выполняется оператор, соответствующий выбранной ветви, после чего управление передается оператору, следующему за ключевым словом end, которое закрывает всю конструкцию case.
- если подходящего списка констант нет, то выполняется оператор, стоящий за ключевым словом else. Если else-ветви нет, то не выполняется ничего.
Иллюстрация if и case
В качестве примера, иллюстрирующего использование операторов ветвления, приведем несколько различных реализаций функции sgn(x)2) - знак числа х. Из математики известно, что эта функция имеет следующие значения:
sgn(x) = -1, если x < 0;sgn(x) = 0, если x = 0;sgn(x) = 1, если x > 0.Реализовать эту функцию для случая, когда х вещественное, можно следующими способами (при условии, что x:real; sgn: -1..1;):
1. if x=0 then sgn:= 0;2. if x<0 then sgn:= -1;3. if x>0 then sgn:= 1;Это так называемая реализация "в лоб". Здесь нет никаких хитростей и никаких попыток оптимизации: даже если сработает первый вариант, второй и третий все равно будут проверены, невзирая на то, что результат уже получен.
4. if x=0 5. then sgn:= 0 6. else if x<0 then sgn:= -1 7. else sgn:= 1;Этот вариант свободен от излишних проверок в случае, если значение переменной не положительно.Эту реализацию следует признать более эффективной, чем предыдущая
8. if x=0 9. then sgn:=010. else sgn:=x/abs(x);Еще одна попытка сократить текст программы. Здесь используется стандартная функция abs(), которая возвращает абсолютное значение аргумента. Проблема в данном случае состоит в том, что "/" - деление дробное, но ведь нам необходим целый, а не вещественный ответ! "Давайте воспользуемся стандартной функцией округления", - скорее всего, скажет внимательный читатель.
11. if x=0 12. then sgn:=013. else sgn:=round(x/abs(x));И действительно, исправленный вариант будет выдавать верный результат.
14. case x=0 of 15. true: sgn:=0; 16. false:17. sgn:=round(x/abs(x)); 18. end;А вот еще один (правда, несколько неестественный) способ с использованием оператора выбора. Вся хитрость этого варианта в том, что выбирающий ветви переключатель обязан принадлежать к перечислимому типу, именно поэтому пришлось заменить "х" на "х = 0". Напомним, что эта операция сравнения выдает результат логического типа boolean, и именно логические константы true и false фигурируют в качестве меток выбора.
Конечно же, мы перебрали далеко не все возможные способы реализации функции sgn(x) (ведь сколько людей, столько и способов выражать свои мысли - хоть в литературе, хоть в программировании). Однако уже на этом простеньком примере видно, что способов запрограммировать желаемое всегда больше, чем один, и вряд ли самое простое решение будет и оптимальным.
Тип данных (встречается также термин вид данных) — фундаментальное понятие теории программирования. Тип данных определяет 1) множество значений, 2) набор операций, которые можно применять к таким значениям и, возможно, 3) способ реализации хранения значений и выполнения операций. Любые данные, которыми оперируют программы, относятся к определённым типам.
Классификация типов данных
Типы данных бывают следующие:
Простые.
o Перечислимый тип. Может хранить только те значения, которые прямо указаны в его описании.
o Числовые. Хранятся числа. Могут применяться обычные арифметические операции.
§ Целочисленные: со знаком, то есть могут принимать как положительные, так и отрицательные значения; и без знака, то есть могут принимать только неотрицательные значения.
§ Вещественные: с запятой (то есть хранятся знак и цифры целой и дробной частей) и с плавающей запятой (то есть число приводится к виду m*2e, где m — мантисса, e — экспонента, причем 1/2<=m<=1, а e — целое число и хранятся знак, и числа m и e).
o Символьный тип. Хранит один символ. Могут использоваться различные кодировки.
o Логический тип. Имеет два значения: истина и ложь. Могут применяться логические операции. Используется в операторах ветвления и циклах. В некоторых языках является подтипом числового типа, при этом ложь=0, истина=1.
o Множество. В основном совпадает с обычным математическим понятием множества. Допустимы стандартные операции с множествами и проверка на принадлежность элемента множеству. В некоторых языках рассматривается как составной тип.
Составные (сложные).
- Массив. Является индексированным набором элементов одного типа. Одномерный массив — вектор, двумерный массив — матрица.
- Строковый тип. Хранит строку символов. Может применяться операция конкатенация (сложение строк). Чаще всего рассматривается как массив символов, но иногда выделяется в качестве простого.
- Запись. Набор различных элементов (полей записи), хранимый как единое целое. Возможен доступ к отдельным полям записи.
- Файловый тип. Хранит только однотипные значения, доступ к которым осуществляется только последовательно (файл с произвольным доступом, включённый в некоторые системы программирования, фактически является неявным массивом).
- Структура. Структура в программировании (struct) позволяет хранить множество однотипных (более простые типы данных, что приведены выше) и/или логически связанных данных.
Порядковые типы
Порядковые типы представляют собой подмножество простых типов. Все простые типы, отличные от вещественных типов, являются порядковыми и выделяются по следующим четырем характеристикам. - Все возможные значения данного порядкового типа представ- ляют собой упорядоченное множество, и каждое возможное значение связано с порядковым номером, который представ- ляет собой целочисленное значение. За исключением значе- ний целочисленного типа, первое значение любого порядко- вого типа имеет порядковый номер 0, следующее значение имеет порядковый номер 1 и так далее для каждого значения в этом порядковом типе. Порядковым номером значения цело- численного типа является само это значение. В любом по- рядковом типе каждому значению, кроме первого, предшест- вует другое значение, и после каждого значения, кроме последнего, следует другое значение в соответствии с упо- рядоченностью типа. - К любому значению порядкового типа можно применить стан- дартную функцию Ord, возвращающую порядковый номер этого значения. - К любому значению порядкового типа можно применить стан- дартную функцию Pred, возвращающую предшествующее этому значению значение. Если эта функция применяется к первому значению в этом порядковом типе, то выдается сообщение об ошибке. - К любому значению порядкового типа можно применить стан- дартную функцию Succ, возвращающую следующее за этим зна- чением значение. Если эта функция применяется к последне- му значению в этом порядковом типе, то выдается сообщение об ошибке. - К любому значению порядкового типа и к ссылке на перемен- ную порядкового типа можно применить стандартную функцию Low, возвращающую наименьшее значение в диапазоне данного порядкового типа. - К любому значению порядкового типа и к ссылке на перемен- ную порядкового типа можно применить стандартную функцию High, возвращающую наибольшее значение в диапазоне данно- го порядкового типа. Синтаксис порядкового типа имеет следующий вид: --------------------- порядковый -----T---->¦ отрезок типа +---------> тип ¦ L--------------------- ^ ¦ --------------------- ¦ +---->¦ перечислимый тип +-----+ ¦ L--------------------- ¦ ¦ --------------------- ¦ L---->¦ идентификатор +------ ¦ порядкового типа ¦ L--------------------- Borland Pascal имеет 10 встроенных порядковых типов: Integer (целое), Shortint (короткое целое), Longint (длинное целое), Byte (длиной в байт), Word (длиной в слово), Boolean (булевское), ByteBool (булевское размером в байт), WordBool (булевское разме- ром в слово), LongBool (длинный булевский тип) и Char (символьный тип). Кроме того, имеется два других класса определяемых пользо- вателем порядковых типов: перечислимые типы и отрезки типов (под- диапазоны).Символьный тип (char)
Множеством значений этого типа являются символы, упорядочен- ные в соответствии с расширенным набором символов кода ASCII. При вызове функции Ord(Ch), где Ch - значение символьного типа, возв- ращается порядковый номер Ch. Строковая константа с длиной 1 может обозначать значение константы символьного типа. Любое значение символьного типа может быть получено с помощью стандартной функции Chr.Перечислимые типы