ВІКІСТОРІНКА
Навигация:
Інформатика
Історія
Автоматизація
Адміністрування
Антропологія
Архітектура
Біологія
Будівництво
Бухгалтерія
Військова наука
Виробництво
Географія
Геологія
Господарство
Демографія
Екологія
Економіка
Електроніка
Енергетика
Журналістика
Кінематографія
Комп'ютеризація
Креслення
Кулінарія
Культура
Культура
Лінгвістика
Література
Лексикологія
Логіка
Маркетинг
Математика
Медицина
Менеджмент
Металургія
Метрологія
Мистецтво
Музика
Наукознавство
Освіта
Охорона Праці
Підприємництво
Педагогіка
Поліграфія
Право
Приладобудування
Програмування
Психологія
Радіозв'язок
Релігія
Риторика
Соціологія
Спорт
Стандартизація
Статистика
Технології
Торгівля
Транспорт
Фізіологія
Фізика
Філософія
Фінанси
Фармакологія


Основой программистской грамотности является развитое алгоритмическое мышление.

ОСНОВЫ ПРОГРАММИРОВАНИЯ

Введение

Программирование все в большей степени становится занятием лишь для профессионалов. Объявленный в середине 1980-х гг. лозунг «Программирование — вторая грамотность» остался в прошлом. В понятие «компьютерная грамотность» сегодня входит прежде всего навык использования многообразных средств информационных технологий. Решая ту или иную информационную задачу, необходимо выбрать адекватное программное средство. Это могут быть электронные таблицы, системы управления базами данных, математические пакеты и т.п. И только в том случае, когда подобные средства не дают возможности решить задачу, следует прибегать к универсальным языкам программирования.

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

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

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

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

· построение алгоритмов из базовых структур;

· применение метода последовательной детализации.

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

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

Процесс изучения и практического освоения программирования делится на три части:

· изучение методов построения алгоритмов;

· изучение языка программирования;

· изучение и практическое освоение определенной системы программирования .

Решению первой задачи посвящены второй и четвертый разделы . Во втором разделе даются основные, базовые понятия и принципы построения алгоритмов работы с величинами. В четвертом разделе излагаются некоторые известные методики полного построения алгоритмов, обсуждаются проблемы тестирования программ, оценки сложности алгоритмов.

Язык программирования Турбо Паскаль излагается в третьем разделе. Подчеркнем, что это - прежде всего учебное пособие по программированию, а не по языку Паскаль. Поэтому исчерпывающего описания данных языков вы здесь не найдете. Языки излагаются в том объеме, который необходим для начального курса программирования. Более подробное описание языков можно найти в книгах, приведенных в списке литературы.

В учебном пособии нет инструкций по работе с конкретными системами программирования для изучаемых языков. С ними студенты должны познакомиться в процессе практики на ЭВМ, используя другие источники.


 

ОСНОВЫ АЛГОРИТМИЗАЦИИ

Алгоритмы и величины

Этапы решения задачи на ЭВМ. Работа по решению любой задачи с использованием компьютера делится на следующие этапы:

1. Постановка задачи.

2. Формализация задачи.

3. Построение алгоритма.

4. Составление программы на языке программирования.

5. Отладка и тестирование программы.

6. Проведение расчетов и анализ полученных результатов.

Часто эту последовательность называют технологической цепочкой решения задачи на ЭВМ. Непосредственно к программированию в этом списке относятся пункты 3, 4, 5.

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

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

Третий этап — построение алгоритма. Опытные программисты часто сразу пишут программы на языках, не прибегая к каким-либо специальным способам описания алгоритмов (блок-схемам, псевдокодам). Однако в учебных целях полезно использовать эти средства, а затем переводить полученный алгоритм на язык программирования.

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

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

• уметь строить алгоритмы;

• знать языки программирования;

• уметь работать в соответствующей системе программирования.

ВВЕДЕНИЕ В ЯЗЫКИ ПРОГРАММИРОВАНИЯ

ПРОГРАММИРОВАНИЕ НА ПАСКАЛЕ

Типы данных

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

 

В стандартном Паскале отсутствует строковый тип. Кроме того, в Турбо Паскале целые и вещественные — это группы типов. В старших версиях Турбо Паскаля существует процедурный тип и тип объект.

Каждый тип имеет свой идентификатор.

В табл. 3.1 представлена информация о простых типах данных, определенных в Турбо Паскале. Для вещественных типов в скобках указано количество сохраняемых значащих цифр мантиссы в десятичном представлении числа.

 

 

Таблица 3.1

 

В стандарте Паскаля из вещественных типов определен только тип Real; из целых типов — Integer.

Типы Single, Double, Extended употребляются в Паскаль-программах только в том случае, если ПК снабжен сопроцессором «плавающей арифметики» (для процессоров IBM PC, начиная с Intel-80486 и старше, это условие всегда выполняется).

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

Описание переменных. Для всех переменных величин, используемых в программе, должны быть указаны их типы. Это делается в разделе переменных программы. Структура раздела переменных показана на рис. 10.

 

Пример раздела переменных программы:

Var m,n,k: Integer;

х,у,z: Real;

Symbol: Char;

Константы. Тип константы определяется по контексту, т.е. по форме ее записи в программе.

Целые десятичные константы записываются в обычной форме целого числа со знаком или без знака, например 25, -24712, 376.

Целые шестнадцатеричные константы записываются с префиксом $. Они должны находиться в диапазоне от $00000000 до $FFFFFFFF.

Вещественные константы с фиксированной точкой записываются в обычной форме десятичного числа с дробной частью. Разделитель целой и дробной части — точка, например: 56.346, 0.000055, -345678.0.

Вещественные константы с плавающей точкой имеют форму:

<мантисса>Е<порядок>

Здесь мантисса — целое или вещественное число с фиксированной точкой, порядок — целое число со знаком или без, например 7Е-2 (7∙10-2), 12.25Е6 (12,25∙106), 1Е-25 (10-25).

Символьная константа — любой символ алфавита, заключенный в апострофы, например, 'W, '!', '9'.

Логическая константа — одно из двух слов: true, false.

Строковая константа — строка символов, заключенная в апострофы, например Turbo Pascal', 'Ответ:', '35-45-79'. Максимальная длина — 255 символов.

Константе может быть поставлено в соответствие определенное имя. Назначение имени константе производится в разделе констант программы. Структура раздела констант показана на рис. 11.

 

Пример:

 

В дополнение к сказанному заметим, что в Турбо Паскале допустимо употребление типизированных констант. Типизированная константа аналогична переменной, которой задается начальное значение. Причем происходит это на этапе компиляции. Описание типизированной константы приведено на рис. 12.

 

Пример:

 

В Турбо Паскале имеется ряд имен, зарезервированных за определенными значениями констант. Ими можно пользоваться без предварительного определения в программе (табл. 3.2).

 

Таблица 3.2

 

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

Для описания типов пользователя в Паскале существует раздел типов, структура которого представлена на рис. 13.

 

Перечисляемый тип (рис. 14) задается непосредственно перечислением всех значений, которые может принимать переменная данного типа.

 

Определенное имя типа затем используется для описания переменных. Например:

 

 

Здесь Gaz и Metal — имена перечисляемых типов, которые ставятся в соответствие переменным Gl, G2, G3 и Metl, Met2. Переменной Day назначается перечисляемый тип, которому не присвоено имя.

Значения, входящие в перечисляемый тип, являются константами. Действия над ними подчиняются правилам, применимым к константам. Каждое значение в перечисляемом типе занимает в памяти 2 байта. Поэтому число элементов не должно превышать 65535.

Перечисляемый тип — упорядоченное множество. Его элементы пронумерованы начиная от 0 в порядке следования в описании.

В программе, в которой присутствует данное выше описание, возможен такой фрагмент:

 

Интервальный тип (рис. 15) задается как упорядоченное ограниченное подмножество некоторого порядкового типа.

 

Порядковый номер первой константы не должен превышать номера второй константы в соответствующем базовом типе.

При исполнении программы автоматически контролируется принадлежность значений переменной интервального типа установленному диапазону. При выходе из диапазона исполнение программы прерывается.

Пример:

Repeat Until KeyPressed;

Это пустой цикл, который «крутится на месте» до нажатия какой-либо клавиши. В это время на экране окно результатов. После нажатия на клавишу значение KeyPressed станет равно True, цикл завершится, будет выполнен переход на метку End и на экран вернется окно редактора. Этот прием можно использовать для задержки выполнения программы в любом ее месте.

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

Repeat Until KeyPressed;

Window(1,1,80,25);

TextBackGround(Black);

CIrScr;

О других процедурах и функциях модуля CRT читайте в книгах по Турбо Паскалю.

Цикл по параметру

Рассмотрим следующую простую задачу: требуется вычислить сумму целых чисел от M до N путем прямого суммирования. Здесь М и N — целые числа. Задачу можно сформулировать так:

 

Алгоритм и программа решения этой задачи с использованием структуры цикл-пока представлены на рис. 23.

 

А теперь введем новый тип циклической структуры, который будет называться цикл по параметру, или цикл-для. Блок-схема и программа на Паскале для решения рассматриваемой задачи с использованием этой структуры приведены на рис. 24.

 

Здесь целая переменная I последовательно принимает значения в диапазоне от М до N. При каждом значении I выполняется тело цикла. После последнего выполнения цикла при I = N происходит выход из цикла на продолжение алгоритма. Цикл выполняется хотя бы один раз, если М ≤ N, и не выполняется ни разу при М > N.

В программе используется оператор цикла For, синтаксическая диаграмма которого представлена на рис. 25.

 

Выполнение оператора For в первом варианте (То) происходит по следующей схеме:

1. Вычисляются значения < Выражения 1> и < Выражения 2>. Это делается только один раз при входе в цикл.

2. Параметру цикла присваивается значение < Выражения 1>.

3. Значение параметра цикла сравнивается со значением < Выражения 2 >. Если параметр цикла меньше или равен этому значению, то выполняется тело цикла, в противном случае выполнение цикла заканчивается.

4. Значение параметра цикла изменяется на следующее значение в его типе (для целых чисел — увеличивается на единицу); происходит возврат к пункту 3.

Оператор цикла For объединяет в себе действия, которые при использовании цикла While выполняют различные операторы: присваивание параметру начального значения, сравнение с конечным значением, изменение на следующее.

Как известно, результат суммирования целых чисел не зависит от порядка суммирования. Например, в рассматриваемой задаче числа можно складывать и в обратном порядке, т.е. от N до М (N ≥ М). Для этого можно использовать второй вариант оператора цикла For:

Summa:=0 ;

For I:=N DownTo M Do

Summa:=Summa+I;

Слово DownTo буквально можно перевести как «вниз до». В таком случае параметр цикла изменяется по убыванию, т.е. при каждом повторении цикла параметр изменяет свое значение на предыдущее (равносильно i:=pred(i)). Тогда ясно, что цикл не выполняется ни разу, если N < М.

 

Работая с оператором For, учитывайте следующие правила:

 

• параметр цикла не может иметь тип Real;

• в теле цикла нельзя изменять переменную «параметр цикла»;

• при выходе из цикла значение переменной-параметра является неопределенным.

 

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

For С:='а' То 'z' Do

Write (С,'-',Ord(C));

Здесь переменная С имеет тип Char.

 

Подпрограммы

С понятием вспомогательного алгоритма вы уже знакомы (см. разд. 1.4). В языках программирования вспомогательные алгоритмы называются подпрограммами. В Паскале различаются две разновидности подпрограмм: процедуры и функции. Рассмотрим этот вопрос на примере следующей задачи: даны два натуральных числа a и b. Требуется определить наибольший общий делитель трех величин: а + b, |а – b|, а • b. Запишем это так: НОД (a + b, |а – b|, а • b).

Идея решения состоит в следующем математическом факте: если х, у, z — три натуральных числа, то НОД(х, у, z) = НОД(НОД(х, у), z). Иначе говоря, нужно найти НОД двух величин, а затем НОД полученного значения и третьего числа (попробуйте это доказать).

Очевидно, что вспомогательным алгоритмом для решения поставленной задачи является алгоритм получения наибольшего общего делителя двух чисел. Эта задача решается с помощью известного алгоритма Евклида (см. раздел 1.3). Запишем его в форме процедуры на алгоритмическом языке.

Процедура Евклид(цел M,N,K);

нач

пока M<>N

нц

если M>N

то M:=M-N

иначе N:=N-M

кв

кц;

K:=M

кон

Здесь M и N являются формальными параметрами процедуры. M и N параметры-аргументы, K — параметр-результат. Основной алгоритм, решающий исходную задачу, будет следующим:

алг задача;

цел а,b,с;

нач ввод(а,b);

Евклид(а+b,|a-b|,с);

Евклид(с,а*b,с);

вывод(с)

кон.

Процедуры в Паскале. Основное отличие процедур в Паскале от процедур в Алгоритмическом языке (АЯ) состоит в том, что процедуры в Паскале описываются в разделе описания подпрограмм, а в АЯ процедура является внешней по отношению к вызывающей программе. Теперь посмотрим, как решение поставленной задачи программируется на Турбо Паскале.

 

Program NOD1;

Var А,В,С: Integer;

Procedure Evklid(M,N: Integer; Var К: Integer);

Begin

While M<>N Do

If M>N

Then M:=M-N

Else N:=N-M;

K:=M

End;

Begin

Write('a=');

ReadLn(A) ;

Write('b=');

ReadLn(B);

Evklid(A+B,Abs(A-B),C);

Evklid(C,A*B,C);

WriteLn('НОД=',C)

End.

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

 

Из диаграммы видно, что процедура может иметь параметры, а может быть и без них .

Чаще всего аргументы представляются как параметры-значения (хотя могут быть и параметрами-переменными). А для передачи результатов используются параметры-переменные.

Процедура в качестве результата может передавать в вызывающую программу множество значений (в частном случае — одно), а может и ни одного. Теперь рассмотрим правила обращения к процедуре. Обращение к процедуре производится в форме оператора процедуры (рис. 28).

 

Если описана процедура с формальными параметрами, то и обращение к ней производится оператором процедуры с фактическими параметрами. Правила соответствия между формальными и фактическими параметрами: соответствие по количеству, соответствие по последовательности и соответствие по типам.

Первый вариант взаимодействия формальных и фактических параметров называется передачей по значению: вычисляется значение фактического параметра (выражения) и это значение присваивается соответствующему формальному параметру. Второй вариант взаимодействия называется передачей по имени: при выполнении процедуры имя формальной переменной заменяется на имя соответствующей фактической переменной (в откомпилированной программе имени переменной соответствует адрес ячейки памяти).

В рассмотренном нами примере формальные параметры М и N являются параметрами-значениями. Это аргументы процедуры. При обращении к ней первый раз им соответствуют значения выражений а + b и abs (а - b); второй раз — с и а • b. Параметр K является параметром-переменной. В ней получается результат работы процедуры. В обоих обращениях к процедуре соответствующим фактическим параметром является переменная с. Через эту переменную основная программа получает результат.

Теперь рассмотрим другой вариант программы, решающей ту же задачу. В ней используется процедура без параметров.

Program NOD2;

Var A,B,K,M,N: Integer;

Procedure Evklid;

Begin

While M<>N Do

If M>N

Then M:=M-N

Else N:=N-M;

K:=M

End;

Begin

Write('a=');

ReadLn(A);

Write('b=');

ReadLn(B);

M:=A+B;

N:=Abs(A-B);

Evklid;

M:=K;

N:=A*B;

Evklid;

WriteLn('HOД равен',K)

End.

Чтобы разобраться в этом примере, требуется объяснить новое для нас понятие: область действия описания.

Областью действия описания любого программного объекта (переменной, типа, константы и т.д.) является тот блок, в котором расположено это описание .

Если данный блок вложен в другой (подпрограмма), то присутствующие в нем описания являются локальными. Они действуют только в пределах внутреннего блока. Описания же, стоящие во внешнем блоке, называются глобальными по отношению к внутреннему блоку. Если глобально описанный объект используется во внутреннем блоке, то на него распространяется внешнее (глобальное) описание.

В программе NOD1 переменные М, N, К — локальные внутри процедуры; переменные а, b, с — глобальные. Однако внутри процедуры переменные а, b, с не используются. Связь между внешним блоком и процедурой осуществляется через параметры.

В программе NOD2 все переменные являются глобальными. В процедуре Evklid нет ни одной локальной переменной (нет и параметров). Поэтому переменные М и N, используемые в процедуре, получают свои значения через оператор присваивания в основном блоке программы. Результат получается в глобальной переменной К, значение которой выводится на экран.

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

Функции. Теперь выясним, что такое подпрограмма-функция. Обычно функция используется в том случае, если результатом подпрограммы должна быть скалярная (простая) величина. Тип результата называется типом функции. В Турбо Паскале допускаются функции строкового типа. Синтаксическая диаграмма описания функции представлена на рис. 29.

 

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

Программа решения рассмотренной выше задачи с использованием функции будет выглядеть следующим образом:

Program NOD3;

Var А,В,Rez:Integer;

Function Evklid(M,N:Integer):Integer;

Begin

While M<>N Do

If M>N

Then M:=M-N

Else N:=N-M;

Evklid:=M

End;

Begin

Write('a=');

ReadLn(A);

Write('b=');

ReadLn(B);

Rez:=Evklid(Evklid(A+B,Abs(A-B)),A*B);

WriteLn('NOD равен',Rez)

End.

Из примера видно, что тело функции отличается от тела процедуры только тем, что в функции результат присваивается переменной с тем же именем, что и функция.

Обращение к функции является операндом в выражении. Оно записывается в следующей форме:

<Имя функции> (<Список фактических параметров>)

Правила соответствия между формальными и фактическими параметрами все те же. Функция позволяет получить результат путем выполнения одного оператора присваивания. Здесь иллюстрируется возможность того, что фактическим аргументом при обращении к функции может быть эта же функция.

По правилам стандарта Паскаля возврат в вызывающую программу из подпрограммы происходит, когда выполнение подпрограммы доходит до ее конца (последний End). Однако в Турбо Паскале есть средство, позволяющее выйти из подпрограммы в любом ее месте. Это оператор-процедура Exit. Например, функцию определения наибольшего из двух данных вещественных чисел можно описать так:

Function Max(X,Y: Real): Real;

Begin

Max:=X;

If X>Y Then Exit Else Max:=Y

End;

Еще раз об области действия описаний. В Паскале неукоснительно действует следующее правило: любой программный объект (константа, переменная, тип и т.п.) должен быть описан перед использованием в программе. Иначе говоря, описание объекта должно предшествовать его первому появлению в других фрагментах программы. Это правило относится и к подпрограммам.

На рис. 30 схематически показана структура взаимного расположения описаний подпрограмм в некоторой условной программе. Попробуем, используя эту схему, разобраться в вопросе об области действия описаний подпрограмм.

 

Любая подпрограмма может использоваться лишь в пределах области действия ее описания. Например, область действия подпрограмм А и В — основная программа. Поэтому из основной программы можно обратиться к подпрограммам А и В. В свою очередь, в подпрограмме В могут быть обращения к подпрограмме А; а из А нельзя обратиться к В, поскольку описание А предшествует описанию В. Подпрограммы А1 и А2 локализованы в подпрограмме A и могут использоваться только в ней; из А2 можно обратиться к A1, но не наоборот.

Из подпрограммы B1 можно обратиться к А, поскольку ее описание является глобальным по отношению к B1, но нельзя обратиться к А1, поскольку область действия описания А1 не распространяется на блок подпрограммы В.

Из подпрограммы В22 можнообратиться только к B21, B1, А.

Если одно и то же имя описано во внешнем блоке (глобально) и во внутреннем блоке (локально), то последнее описание (локальное) перекрывает первое в пределах внутреннего блока. Рассмотрим следующий пример:

Program Example1; Program Example2;

Var X: Integer; Var X: Integer;

Procedure P; Procedure P;

Var X: Integer; Begin

Begin WriteLn('x=',X) WriteLn('x=',X)

End; End;

Begin X:=1; Begin X:=l;

P P

End. End.

Что выведется на экран в результате работы программы Example1 и Example2? Первая программа выдаст результат:

х=...

На месте многоточия будет какое-то произвольное значение, соответствующее неопределенной величине х. Вторая программа в результате даст

х=1

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

Во втором примере переменная х одна на всю программу. Она описана глобально. Поэтому значение 1, присвоенное ей в основной программе, передается и в подпрограмму.

Далее разговор пойдет о ситуации на первый взгляд совершенно парадоксальной. Оказывается, подпрограмма в своем описании может содержать обращение к самой себе. Такая подпрограмма называется рекурсивной.

Рекурсивные подпрограммы. В математике рекурсивным называется определение любого понятия через самое себя. Классическим примером является определение факториала целого числа, большего или равного нулю:

 

Здесь функция факториала определена через факториал. Нетрудно понять справедливость такого определения. Для п > 0

 

Вариант 0!=1 является тривиальным. Но это «опорное» значение, от которого начинается раскручивание всех последующих значений факториала:

 

Рассмотрим подпрограмму-функцию, использующую в своем описании приведенную выше рекурсивную формулу.

Function Factor(N: Pozint): Pozint;

Begin

If N=0

Then Factor:=1

Else Factor:=N*Factor(N-l)

End;

Предполагается, что тип PozInt объявлен глобально следующим образом:

Type PozInt=0..MaxInt;

Пусть в основной программе для вычисления в целой переменной х значения 3! используется оператор

X:=Factor(3);

При вычислении функции с аргументом 3 произойдет повторное обращение к функции Factor(2). Это обращение потребует вычисления Factor(1). И наконец, при вычислении Factor(0) будет получен числовой результат 1. Затем цепочка вычислений раскрутится в обратном порядке:

Factor(1)=l*Factor(0)=1

Factor(2)=2*Factor(1)=2

Factor(3)=3*Factor(2)=6.

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

Использование рекурсивных функций — красивый прием с точки зрения программистской эстетики. Однако этот путь не всегда самый рациональный. Рассмотренную задачу с п! можно решить так:

F:=l;

For I:=l To N Do

F:=F*I;

Очевидно, что такой вариант программы будет работать быстрее, чем рекурсивный. И в том случае, когда важнейшим является сокращение времени выполнения программы, следует отдать предпочтение последнему варианту.

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

Рекурсивно определена может быть не только функция, но и процедура.

 

Основные понятия и средства компьютерной графики в Турбо Паскале

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

Начиная с четвертой версии Турбо Паскаля для IBM PC появилась мощная графическая библиотека, организованная в модуль Graph. В приложении 2 в справочной форме дано описание основных компонент этого модуля. В рассмотренных ниже примерах программ используется модуль Graph. Для его подключения в начале программы необходимо написать строку:

Uses Graph;

Графические режимы экрана отличаются:

• размером графической сетки (M x N, где М — число точек по горизонтали, N — число точек по вертикали);

• цветностью (число воспроизводимых на экране цветов).

 

Для установки графического режима экрана существуют соответствующие процедуры. В модуле Graph процедура установки графического режима экрана имеет следующий заголовок:

Procedure InitGraph(Var Driver,Mode: Integer; Path: String);

Здесь целая переменная Driver определяет тип графического драйвера; целая переменная Mode задает режим работы графического драйвера; Path — выражение типа String, содержащее маршрут поиска файла графического драйвера.

Список констант модуля Graph, определяющих типы драйверов и режимы, приведен в табл. П2.1 приложения 2.

Вот пример программы, инициализирующей графический режим VGAHi для работы с драйвером VGA (монитор типа VGA).

 

Uses Graph;

Var Driver,Mode: Integer;

Begin

Driver: = VGA;{драйвер}

Mode: = VGAHi;(режим работы}

InitGraph(Driver,Mode,'C:\TP\BGI');

 

Здесь указывается, что файл egavga.bgi с драйвером для VGA-монитора находится в каталоге C:\TP\BGI. Режим VGAHi соответствует графической сетке 640 х 480 с палитрой из 16 цветов.

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

Driver:=Detect;

InitGraph(Driver,Mode,'C:\TP\BGI');

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

В модуле Graph процедура возвращения в текстовый режим имеет заголовок:

Procedure CloseGraph;

Строковый тип данных

Теперь мы познакомимся с типом данных, который относится к числу структурированных. Это строковый тип данных (строка). Следует заметить, что строковый тип данных есть в Турбо Паскале и отсутствует в стандартном Паскале.

Строка — это последовательность символов. Каждый символ занимает 1 байт памяти (код ASCII). Количество символов в строке называется ее длиной. Длина строки может находиться в диапазоне от 0 до 255. Строковые величины могут быть константами и переменными.

Строковая константа есть последовательность символов, заключенная в апострофы. Например:

'Язык программирования ПАСКАЛЬ',

'IBM PC — computer',

'33-45-12'.

Строковая переменная описывается в разделе описания переменных следующим образом:

Var <идентификатор>: String[<максимальная длина строки>]

Например:

Var Name: String[20]

Параметр длины может и не указываться в описании. В таком случае подразумевается, что он равен максимальной величине — 255. Например:

Var slovo: String

Строковая переменная занимает в памяти на 1 байт больше, чем указанная в описании длина. Дело в том, что один (нулевой) байт содержит значение текущей длины строки. Если строковой переменной не присвоено никакого значения, то ее текущая длина равна нулю. По мере заполнения строки символами ее текущая длина возрастает, но она не должна превышать максимальной по описанию величины.

Символы внутри строки индексируются (нумеруются) от единицы. Каждый отдельный символ идентифицируется именем строки с индексом, заключенным в квадратные скобки. Например:

Name[5], Name[i], slovo[k+1].

Индекс может быть положительной константой, переменной, выражением целого типа. Значение индекса не должно выходить за границы описания.

Тип String и стандартный тип char совместимы. Строки и символы могут употребляться в одних и тех же выражениях.

Строковые выражения строятся из строковых констант, переменных, функций и знаков операций. Над строковыми данными допустимы операции сцепления и операции отношения.

Операция сцепления (+) применяется для соединения нескольких строк в одну результирующую строку. Сцеплять можно как строковые константы, так и переменные.

Например:

'ЭВМ'+'IВМ'+'РС'.

В результате получится строка:

'ЭВМ IBM PC'.

Длина результирующей строки не должна превышать 255. Операции отношения =, <

, >, <=, >=, <> производят сравнение двух строк, в результате чего получается логическая величина (true или false). Операция отношения имеет более низкий приоритет, чем операция сцепления. Сравнение строк производится слева направо до первого несовпадающего символа, и больше считается та строка, в которой первый несовпад

© 2013 wikipage.com.ua - Дякуємо за посилання на wikipage.com.ua | Контакти