русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Основной блок функции


Дата добавления: 2014-09-02; просмотров: 808; Нарушение авторских прав


End;

 

Глобальные и локальные переменные, формальные и фактические переменные и параметры в функциях и процедурах в языке Pascal

Термин «ЛОКАЛЬНЫЙ» применимо к меткам, константам и переменным, описанным в разделе FUNCTION, означает, что эти метки, константы и переменные с этими именами могут фигурировать лишь в тексте основного блока функции. При этом следует давать имена локальным переменным, константам и даже – входным параметрам, отличающиеся от имен параметров, фигурирующих в основном блоке программы (так называемых ГЛОБАЛЬНЫХ параметров) во избежание путаницы.

Совпадение меток может привести к выдаче сообщения об ошибке «Duplicate Label Number», а локальная переменная «перекроет» свою глобальную напарницу, что очень трудно предугадать в процессе анализа программы. Приведенная структура в точности копирует в миниатюре структуру программы. Тогда текст функции перевода из градусов в радианы (назовем ее GradRad) будет выглядеть так:

 

Function GradRad(fi:real):real;

begin

GradRad:=fi*Pi/180;

end;

При описании и в тексте функции фигурирует не конкретное значение, а некоторый параметр ‘fi’, для которого и выписана формула. Такой параметр называется ФОРМАЛЬНЫМ. Потом, после вызова функции (например, GradRad(17)) в нее будет передано конкретное значение аргумента (17), для которого функция и будет вычислена. Такой параметр называют ФАКТИЧЕСКИМ.

Для перестраховки fi описан типом real, хотя в нашем примере значения целы. Зато именно такой текст функции годится для любой программы.

Примечание. Тригонометрические функции sin(x) и cos(x) обрабатывают аргумент, представленный в радианной, а не градусной мере. Поэтому выражение sin(30) соответствует синусу 30 радиан, а не 30 градусов и, следовательно, не равно 0.5. Аргумент может быть пересчитан из градусной меры в радианную по формуле



Соответственно значение функции ArcTan(x) получается в радианной мере, и для его пересчета в градусы используют формулу

 

 

Пример:Вычислить значение

 

Program Trigonometry;

Uses crt; {стандартная библиотека}

Var {раздел описания переменных}

y: real;

Function GradRad(fi: real):real; {функция перевода угла из градусной меры в радианную}

Begin

GradRad:=fi*pi/180

End;

Begin

ClrScr;

y:=sin(GradRad(17))-cos(GradRad(82));

y:=y+sin(GradRad(28))/cos(GradRad(28));

Writeln(' y= ', y:6:2); {вывод на экран результата}

Repeat Until KeyPressed; {стандартная функция из библиотеки CRT, приводит

к задержке окна результатов до нажатия любой клавиши}

End.

 

Результат работы программы y=0.685.

 

Процедуры Procedure

 

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

 

Примечание:

Процедура Назначение процедуры Аргумент Примеры
Inc(x) увеличение целого х на 1 Integer inc(d)
Inc(x,k) увеличение целого х на k Integer inc(x, -2)
Dec(x) уменьшение целого х на 1 Integer dec(i)
Dec(x,k) уменьшение целаго х на k Integer dec(j,6)
Randomize изменение программы генерации случайных чисел ______ ______

 

Пример:

Пусть необходимо поменять местами значения вводимых переменных х и у. Эта операция весьма распространена. Поэтому имеет смысл сделать ее стандартной, описав как процедуру. Назовем ее “Swap” (перестановка). Этой процедуре необходимо подавать значения двух переменных. При организации процедур важно помнить одно правило: если передаваемые в процедуру параметры будут в ней изменяться, их описание следует предварять словом Var. Тогда программа примет вид:

Program Change;

Uses CRT; {стандартная библиотека}

Var

x, y:Real;

Procedure Swap(Var aa, bb:real);

Var rr:Real;

Begin

rr:=aa; aa:=bb; bb:=rr

end;

Begin

Write(‘x= ‘); Readln(x);

Write(‘y= ‘); Readln(y);

Swap(x,y);

Writeln(‘x= ‘,x:4:1,’ y = ‘,y:4:1); {вывод на экран результата}

Repeat Until KeyPressed; {стандартная функция из библиотеки CRT, приводит

к задержке окна результатов до нажатия любой клавиши}

End.

Результат работы программы:

x=4

y=6

x= 6.0 y= 4.0

 

 

Условные операторы

Условные операторы позволяют проверить некоторое условие и в зависимости от результатов проверки выполнить то или иное действие. Таким образом, условные операторы – это средство ветвления вычислительного процесса.

Следует отметить:

v выбор последовательности операторов осуществляется во время выполнения программы в зависимости от выполнения условия;

v условие – это выражение логического типа, которое может принимать одно из двух значений: true (истина-условие выполняется) или false (ложь-условие не выполняется);

v при помощи логических операций and (логическое «И») и or (логическое «ИЛИ») из простых условий можно строить сложные.

 

Оператор ‘IF-THEN’

Оператор IF-THEN (“Если-то”) форма записи имеет вид:

If (условие) Then Begin

Оператор;

Оператор;

...

End;

Работает следующим образом: Если стоящее в скобках условие истинно, то выполняются операторы, стоящие между Begin и End, а если ложно – программа сразу переходит на конец оператора.

Отличие оператора If-Then от оператора If-Then-Else состоит в том, что условная структура If-Then-Else реализует так называемое двойное ветвление.

 

Пример 1. Вычислить квадратный корень из числа x.

При вводе отрицательного значения x ЭВМ выведет сообщение об ошибке “Invalid Floating Point Operation”. Нужно составить программу, которая в случае отрицательного значения x выводила на экран сообщение: 'Недопустимое значение', в случае x>=0 выводила результат.

Фрагмент программы:

Write(‘x =’); Readln(x);

If (x>=0) Then

Begin

y:=Sqrt(x);

Writeln(‘Sqrt(x)=’,y:6:2);

End;

If (x<0) Then Write (‘Недопустимое значение’);

 

Любое условие есть величина логическая (типа Boolean), принимающая значение True в том случае, когда условие истинно, и False – в обратном случае. В силу этого обстоятельства условие

If (x<0) then Оператор;

являет собой сокращенную запись условия

 

If ((x<0)=True) then Оператор;

Более краткое If (x<0) then Оператор;

 

 

Оператор ‘IF-THEN-ELSE’

Оператор IF-THEN-ELSE (“Если-То-Иначе”) предусматривает двойное ветвление, форма записи имеет вид:

If (условие) Then

Begin

Оператор1;

End

Else

Begin

Оператор2;

End;

Поставленная после первого End точка с запятой ‘;’ (разделитель операторов) приведет к ошибке, тогда будет означать конец оператора. После ELSE точку с запятой не ставить.

Пример1.Найти максимум из двух целых чисел a и b, введенных с клавиатуры.

Фрагмент программы:

if (a>b) then max:=a else max:=b;

 

Тройное ветвление

Выбор идет из трех возможных вариантов.

 

Пример 1Ввести x и вычислить y:

 

Program TI_1;

Uses crt;

Var x,y:real;

Begin

Write(‘x=’); readln(x);

If x<-1 then y:=ln(abs(x)) else

If (x>=-1) and (x<0) then y:=sin(x) else y:=cos(x);

Writeln(‘x=’,x:5:2,’ y=’,y:5:2);

Readkey; {функция будет ожидать нажатия на любую клавишу}

End.

b<c
+
+
_
_
min:=c
_
+
min:=b
min:=a
a<c
a<b
Алгоритм поиска min и max и его программная реализация

Блок схема

 

 

Пример 1.Найти min из трех вещественных чисел.

Program Poiskmin;

Uses crt;

Var a,b,c,min:real;

Begin

Write(‘a=’); Readln(a);

Write(‘b=’); Readln(b);

Write(‘c=’); Readln(c);

If (a<b) Then If (a<c) Then min:=a Else

If (b<c) then min:=b Else min:=c;

Writeln(‘min(a,b,c)=’,min:6:2);

Repeat Until KeyPressed;

End.

 

 

Пример 2.Найти max из трех вещественных чисел.

 

Фрагмент программы:

If (a>b) Then If (a>c) Then max:=a Else

If (b>c) then max:=b Else max:=c;

 

Более сокращенный вариант

If (a>b) Then max:=a Else max:=b;

If (c>max) Then max:=c;

 

Оператор варианта ‘CASE…OF’

 

Сложное ветвление N-го порядка имеет один существенный недостаток: Приходится писать большое количество однотипных операторов IF-THEN-ELSE. Такую структуру может заменить компактный оператор варианта CASE-OF. Синтаксис этого оператора представлен ниже:

 

CASE имя_переменной OF

<Вариант1> : [Оператор_1];

………………….

<ВариантN> : [Оператор_N];

ELSE [Оператор_N+1];

END;

 

 

Если переменная с именем, указанным после CASE, принимает значение одного из нижеприведенных диапазонов, то выполняется соответствующий блок операторов. Если ни в один из диапазонов ее значение не попадает, то выполняется альтернативные операторы, стоящие после ELSE. Если же альтернативная ветвь отсутствует, то программа выходит из оператора, ничего не исполнив.

 

Пример:

 

Program ZACHET;

Uses crt;

Label metka;

Var examination:char;

Begin

metka: write(‘зачет (Y/N)?-’);

readln(examination);

Case examination of

‘Y’: write(‘зачет’);

‘N’: write(‘не зачет’);

‘I’: write(‘не явка’);

Else Goto metka;

End;

Repeat Until KeyPressed;

End.

 

На экране

зачет (Y/N)?-Да нужно повторить ввод, т.к. набрано на русском языке.

зачет (Y/N)?-Y

зачет

Лекция 7

Циклические структуры. Вложенные циклы. Рекурсивные функции. Операторы прерывания.

 

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

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

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

- Вложенные циклы – это, когда определённый цикл повторяется многократно в другом цикле охватывающем данный.

 

Определенные циклы ‘FOR…DO…’

Определенный цикл FOR-DO (цикл со счетчиком) имеет следующую структуру:

(ОТ ДО)

FOR <перем_цикла>:=<нач_знач> TO <конеч_знач> DO

Begin

<тело_цикла>

End;

<перем_цикла> - переменная цикла- любая переменная целочисленного типа (Например INTEGER, кроме REAL). Переменную цикла также называют счетчиком.

<нач_знач> - начальное значение - выражение того же типа;

<конеч_знач> - конечное значение - выражение того же типа;

<тело_цикла> - произвольная последовательность операторов Турбо Паскаля;

При выполнении оператора FOR вначале вычисляется выражение <нач_знач> и осуществляется присваивание <перем_цикла>:=<нач_знач>. После этого циклически повторяется:

- проверка условия <перем_цикла> <= <конеч_знач>; если условие не выполнено, оператор FOR завершает свою работу;

- выполнение операторов входящих в <тело_цикла>;

- наращивание переменной <перем_цикла> на единицу;

Первая форма записи оператора FOR с последовательным увеличением счетчика.

ü Для целой переменной строится цикл с шагом +1 по возрастанию параметра

for i:=1 to 8 do Оператор;

В этом случае i последовательно принимает значения 1,2,3,..,8.

ü Попытка организовать цикл «от большего к меньшему»

for i:=8 to 1 do Оператор;

не приведет к ошибке, но будет пройден лишь один шаг (i=8).

 

Пример: Написать программу для вычисления суммы N первых натуральных чисел, т.е. требуется вычислить 1+2+3+…N

 

Program PRIMER;

Var

N: integer; {последнее число суммы- исходное данное}

i, s :integer; {счетчик цикла и слагаемое, сумма результата}

Begin

Write(‘N’);Readln(N); {Вводим значение N}

s:=0; {Начальное значение суммы}

for i:=1 to N do {Цикл подсчета суммы}

s:=s+i;

Writeln(‘S = ’, s); {вывод на экран результата}

End.

 

Замечание 1. Условие <перем_цикла> <= <конеч_знач>, управляющее работой

цикла FOR-DO проверяется перед выполнением тела цикла: если условие не выполняется в самом начале работы цикла FOR-DO, цикл не будет выполнен ни разу.

Замечание 2. Шаг наращивания параметра цикла строго постоянен и равен 1.

Замечание 3. Внутри тела цикла нельзя менять значения переменной цикла, то есть если i – переменная цикла, то в цикле недопустимо присвоение i какого-нибудь значения: i:=5 неверно.

 

Вторая форма записи оператора FOR c уменьшением счетчика:

FOR <перем_цикла>:=<нач_знач> DOWNTO <конеч_знач> DO

Begin

<тело_цикла>

End;

 

Замена зарезервированного слова TO на DOWNTO означает, что шаг наращивания переменной цикла равен (-1).

 

Пример . for i:=8 downto 2 do Оператор;

В этом случае i последовательно принимает значения 8,7,6,…2

 

 

Пример. Написать программу для вычисления суммы N первых натуральных, т.е. требуется вычислить 1+2+3+…N

Фрагмент программы:

s:=0;

for i:=N downto 1 do {от N до 1 вниз}

s:=s+i;

 

Замечание: Если в цикле выполняется один оператор, то его можно не ставить в последовательно операторов Begin-End.

 

 

Циклы с постусловием ‘REPEAT…UNTIL…’

(Повтор Пока не готовы)

Синтаксис оператора цикла REPEAT…UNTIL:

REPEAT

<тело_цикла>

{операторы begin-end не требуются}

UNTIL <логическое условие>

 

Здесь REPEAT, UNTIL – зарезервированные слова (повторять до тех пор, пока не будет выполнено условие);

Операторы <тело_цикла> выполняются хотя бы один раз, после чего вычисляется выражение <условие>: если его значение есть FALSE (ложь), операторы <тело_цикла> повторяются, в противном случае оператор REPEAT…UNTIL завершает свою работу.

Обратите внимание: пара REPEAT…UNTIL подобна операторным скобкам begin…end, поэтому перед Until ставить точку с запятой необязательно.

 

Алгоритм выполнения: Выполнять тело цикла, пока не станет истинным(true) условие, т.е. пока условие ложно (false) выполняется цикл. После слова UNTIL надо записывать условие завершение цикла. Даже если условие сразу окажется истинным, цикл выполнится хотя бы один раз.

1) Выполнение цикла продолжается, если проверка логического условия дает результат ложь;

2) Если логическое условие выполнено выход из цикла.

 

Пример. Написать программу для вычисления суммы N первых натуральных, т.е. требуется вычислить 1+2+3+…N

 

Фрагмент программы

s:=o; {начальное значение суммы)

i:=1; {начальное значение счетчика и слагаемое}

REPEAT

s:=s+i; {добавим слагаемое к сумме}

i:=i+1; {увеличение значения счетчика и слагаемое на 1}

UNTIL i>N; {вып. пока ложно, условие завершение цикла)

 

Циклы с предусловием ‘WHILE…DO…’

(Пока Делать)

 

Синтаксис оператора цикла ‘WHILE…DO…’:

WHILE <логическое условие> DO

Begin

<тело_цикла>

End;

Здесь WHILE, DO – зарезервированные слова (пока [выполняется условие] делать);

 

Если выражение <условие> имеет значение TRUE (истина), то выполняется <тело_цикла>, после чего вычисление выражения <условие> и его проверка повторяются. Если условие имеет значение FALSE (ложь), оператор WHILE прекращает свою работу.

 

Замечание. Если <тело_цикл> состоит из одного оператора, слова begin end могут быть опущены.

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

While проверялось условие продолжения цикла.

После WHILE записывать условие выполнения операторов цикла.

Пример. Написать программу для вычисления суммы N первых натуральных, т.е. требуется вычислить 1+2+3+…N

Фрагмент программы

s:=o; {начальное значение суммы)

i:=1; {начальное значение счетчика и слагаемое}

WHILE i<=N DO {нужно выполнить цикл N раз}

s:=s+i; {добавим слагаемое к сумме}

i:=i+1; {увеличение значения счетчика и слагаемое на 1}

End; {законченное тело цикла}

Пример. Вычислить факториал числа N(N!).

ФАКТОРИАЛОМ называют такую функцию целочисленного аргумента

f(i), что f(0) = 1 ; f(i) = i * f(i-l)

Тогда

f(l) = l*f(0) =1*1 = 1

f(2) = 2*f(l) = 2*1 = 2

f(3) = 3*f(2) = 3*2*1 = 6

f(4) = 4*f(3) = 4*3*2*1 = 24 и т.д.

 

Получаем, что факториал числа N - это произведение всех натуральных чисел от 1 до N. Дополнительная трудность заключается в том, что факториал нуля есть 1 (как результат договора между математиками), а факториал отрицательного аргумент не определен. Убедитесь самостоятельно в том, что поставленная задача решается с помощью программы:

Program Factorial;

Uses CRT;

Label start;

Var

n,i:Integer;

t:LongInt;

Begin

start:ClrScr;

Write('N = '); Readln(n);

If (n<0) Then Begin

Writeln('N>=0!!!');

Goto start;

End

Else If (n=0) Then t:=l

Else Begin t: = l;

for i:=l to n Do t:=t*i;

End;

Writeln('Факториал числа ',n,' равен ',t);

Repeat Until KeyPressed

End.

Ответ:

N = -3

N>=0!!!

N- = 8

Факториал числа 8 равен 40320

 

Если не поставить начальное значение t=l перед циклом, то по умолчанию ЭВМ обнулит t, из-за чего и все произведение будет равно нулю. Заметьте, что факториал настолько быстро растет,что результат пришлось описывать типом LongInt. Уже 8! оказалось больше числа MaxInt.

Пример. Вычислить сумму S=ln3+ln5+ln7+…

при условии, что в нее входят слагаемые, не превосходящие 5, и количество этих слагаемых.

Логика построения суммы очевидна: s:=s+ln(i)/ Главная проблема заключается в постановке условия на выход из цикла.

Program Logorif;

Uses CRT;

Var

i, j: byte; a, s:real;

Begin

ClrScr;

j:=1; i:=3; a:=ln(i); s:=0;

While (a<5) do

Begin

s:=s+a;

inc(j); inc(i,2);

a:=ln(i);

End;

Writeln(j-1, ' slagaemich');

Writeln('сумма = ',s:7:3);

Repeat Until KeyPressed; {стандартная функция из библиотеки CRT, приводит к задержке окна

результатов до нажатия любой клавиши}

End.

 

Результат работы программы 73 слагаемых, сумма=296.140.

 

Вложенные циклы

 

Вложенные циклы – это структура, при которой один цикл вносится в другой. Пример рассмотрим на практическом занятии.

 

Рекурсивные функции

 

В ряде случаев удается создать цикл, не прибегая к операторам FOR-DO,REPEAT-UNTIL, WHILE-DO с помощью функции или процедуры, такие функции вызывающие сами себя, называют рекурсивными, а процесс их вычисления – рекурсией.

 

Пример. Вычислить: s=(1+sin(2++sin(3+…+sin(14+sin(15)))))

 

Структура похожа на матрешку: внешний синус sin(1+…) имеет аргументом следующий синус sin(2+…) и т.д. Введем функцию FUN, которая будет при вычислении синуса вызывать себя же, но для большего значения аргумента.

Program Recurcia;

Uses CRT;

Function Fun(x:Byte):Real;

Begin

If (x=15) Then Fun:=Sin(x)

Else Fun:=Sin(x+Fun(x+1));

End;

Begin

ClrScr;

Writeln('F= ',Fun(1):6:3);

Repeat Until Keypressed; End. Ответ: F=0.994

 

Операторы прерывания

Операторы Break и Continue

введены в язык Турбо Паскаль версии 7.0 для удобного управления ходом цикла.

1)Break ([breik]перевод с англ. – прерывать)– выход из цикла, прерывание выполнения цикла.

2)Continue (перевод с англ. – продолжать) – переход к следующему шагу цикла.

Пример. Найти сумму S=2+4+6…, не превосходящую 100.

Заметим, что цикл по четным числам можно завести различными способами: Цикл FOR_DO с проверкой условия IF(Not ODD(i)); Цикл While_Do или Repeat_Until с увеличением параметра цикла на два Inc(i,2) и т. п. С использованием оператора “CONTINUE” возможна и другая логика – завести цикл FOR_DO по значениям, идущим подряд, но при появление нечетных значений переходить к следующей итерации цикла. Далее, когда сумма превысит 100, можно выйти из цикла с помощью BREAK. Тогда текст программы:

Program sum1;

Uses CRT;

Var

s: integer; i: byte;

Begin

ClrScr;

s:=0;

For i:=1 to High(Byte) do {Стандартные функции}

begin

if Odd(i) then Continue;

s:=s+i;

if (s>100) then break;

end;

s:=s-i;

Writeln(' s= ',s); Repeat Until Keypressed; End.

Лекция 8

Обработка одномерных и двумерных массивов

 

Понятие и описание массива

Массив – это совокупность однотипных данных, хранящихся в последовательных ячейках памяти и имеющих общее имя. Ячейки называются элементами массива. Все элементы пронумерованы по порядку, и этот номер называется индексом элемента массива. Все элементы массива имеют один и тот же тип данных. Сам массив при этом имеет имя – одно для всех элементов. Для обращения к конкретному элементу массива нужно указать имя массива и в квадратных скобках индекс элемента.

Описание массива

<Имя массива>:array[<тип индекса>] of <тип компонентов>;

<тип компонентов> - это тип данных, который имеет каждый элемент массива,

<тип индекса>-границы изменения индекса.

Var t:array[1..7] of integer;

Примеры одномерного, двухмерного, трехмерного массивов

Рассмотрим пример одномерного массива.

Type

Massive=array[1..7] of Integer;

Var

T: Massive;

Сейчас Massive - это тип, соответствующей последовательности из семи целочисленных чисел (одномерный массив длины 7):

t[1] t[2] t[3] t[4] t[5] t[6] t[7]

Индекс i=1 2 3 4 5 6 7

t[1] – обозначение 1-го элемента массива

Замечание. Попытка извлечь элемент с индексом, не лежащим в диапазоне от 1 до 7 приведут к сообщению об ошибке Constant out of Range (вне установленных рамок).

Двухмерный массив t[i,j] характеризуется двумя индексами .

t[1..4,1..7] – это двумерный массив размерности 4х7

Type

Matrix=array[1..4,1..7] of integer;

Var T:Matriix;

Трехмерный массив t[i,j,k] характеризуются тремя индексами – размерность 4х7х12, а тип описывается так:

Type

Massive=array[1..12] of integer;

Matrix=array[1..4,1..7] of integer;

Var

T:Matrix of Massive;

Замечание. В Паскале размерность массива практически неограниченна. Единственное ограничение заключается в том, что размер возникающей структуры не должен превышать примерно 64 КБ. Пример если массив состоит из вещественных чисел (6 байт), то их не может быть более 10797; аналогичный предел для чисел типа Integer (2 байта) – 32392.

 

Способы ввода одномерных массивов:

Предположим, что массив уже описан в программе. Например:

Const n=15;

Type Massive=array[1..n] of integer; {Определение типов ‘TYPE’}

Var {Описание переменных}

a: array [0..8] of string[20];

b, с : array [10..n+5] of real;

d: Massive;

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

1. Способ последовательное присваивание элементам массива соответствующий значений.

Фрагмент программы:

Const n=10;

Var

a: array [2..n] of integer;

Begin

a[2]:=-4,a[4]:=-6; a[5]:=10; a[9]:=-12;

В результате в соответствующие ячейки ленточки ‘a’ заносятся нужные значения, а остальные элементы по-прежнему равны нулю:

-4 -6 -12
t[2] t[3] t[4] t[5] t[6] t[7] t[8] t[9] t[10]

Eсли в массиве много элементов, но не вводить же 50 элементов массива пятьюдесятью операторами присваивания!

 

2. Способ ввода массива с клавиатуры.

Стандарт ввода массива A из n элементов:

For i:= 1 to n do Begin

Write(‘a[‘,i,’]=?);

Readln(a[i]);

End;

 

В результате запрашивается последовательно элементы массива a[1]=?, a[2]=?, …a[n]=? Этот способ ввода хорош тем, что пользователь видит элементы, которые вводит. Но, ошибившись с вводом одного элемента, он вынужден продолжать ввод, пока не закончится цикл. Далее, при повторном запуске программы пользователю придется вновь вводить те же самые элементы. Поэтому предпочтительнее последующие способы ввода.

 

3. Способ ввода массива, заданного формулой.

Этот способ ввода наиболее прост, удобен, но реализуется он редко из-за того, что в нашем мире мало что происходит по формулам. Введем массивы А, В, С, D такие, что:

A – массив заглавных латинских букв;

B – массив четных байтовых чисел;

C – массив степеней двойки от нулевой до двадцатой;

D – массив, где каждый элемент равен синусу его номера, а номера не превосходят 100.

Соответствующий фрагмент программы:

Var i: byte; t :LongInt;

a: array [1..26] of Char;

b: array [0..50] of Byte;

c: array [0..20] of LongInt;

d: array [0..100] of Real;

Begin

For i:=1 to 26 do a[i]:=chr(i+64);

For i:=0 to 50 do b[i]:=2*i;

t:=1; c[0]:=1;

For i:=1 to 20 do begin

t:=t*2; c[i]:=t;

end;

For i:=0 to 100 do d[i]:=sin(i);

 

Заметьте, во-первых, что ASCII – коды заглавных латинских изменяются от 65 до 90, что и позволяет реализовать формулу a[i]:=chr(i+64);. Во-вторых, степени двойки накапливались в целочисленной ячейке t, что чуть более громоздко, чем реализация формулы b[i]:=exp(i*ln(2)), но зато получается результат целого, а не вещественного типа.

 

4. Способ ввода массива через типизированные константы.

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

Const n=10;

Type Massive=array[1..n] of Real;

Const

a: Massive=(-2,0,8,9,5,-9,2,0,6,-7);

Теперь в программе вполне можно использовать массив а[i] из 10 элементов с начальными значениями a[1]:=-2.0, a[2]:=0.0… Если мы изменим количество элементов в большую или меньшую сторону, то вырезаемая в структуре TYPE-CONST ленточка окажется или слишком большой, или слишком маленькой для восьми перечисляемых чисел. В результате ЭВМ сообщениями об ошибках либо предложит добавить числа в перечень, либо выбросить из него последние числа. Это снижает универсальность ввода.

 

5. Способ ввода массива через генератор случайных чисел.

Если конкретные значения элементов массива не играют роли, то можно позволить себе ввести их случайным образом. Для этого необходимо знать: 1) Тип элементов массива, 2) Примерный диапазон их возможных значений.

Генерация случайных чисел осуществляется с помощью функций Random или Random(N). В первом случае генерируется случайное ВЕЩЕСТВЕННОЕ число от 0 до 1. Если умножить Random на число N, то будет получено случайное ВЕЩЕСТВЕННОЕ число от 0 до N. Функция Random(N) производит генерацию случайного ЦЕЛОГО числа от 0 до N.

Пример. Сгенерируем 10 случайных целых чисел, заключенных на отрезке от 0 до 100:

Program Random_Int;

Uses CRT;

Var

i: byte;

Begin

{ Randomize; }

For i:=1 to 10 do Write(Random(100),’ ‘);

Writeln;

Repeat Until KeyPressed;

End.

 

Результат работы программы:

0 3 86 20 27 67 31 16 37 42

Запустим программу еще раз. Вновь получим ряд чисел:

0 3 86 20 27 67 31 16 37 42

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

6 47 70 17 41 40 70 80 50 35

И еще раз:

4 16 21 3 29 60 74 33 73 32

Если требуется получить случайные числа x, принадлежащие отрезку [a,b], можно воспользоваться формулами:

x:=a+Random(b-a) - для целых чисел;

x:=a+(b-a) *Random- для вещественных чисел;

В приведенных соотношениях генератор случайных чисел в первую очередь масштабируется по длине отрезка (b-a), а потом результат сдвигается на а.

 

Печать массива

Пусть в программе уже стандартизирована константа N, соответствующая количеству элементов массива, и сам тип Massive:

Const n=15;

Type Massive=array[1..n] of real;

Тогда печать массива целесообразно оформить как процедуры, учитывая то, что эта операция выполняется довольно часто:

Procedure PrintMas(aa: Massive);

Var ii: byte;

Begin

Writeln;

For ii:=1 to n do Write(aa[ii]:6:2,’ ‘); {вывод на экран результата}

Writeln; Writeln;

End;

Заметим, что процедура вызывается PrintMas(Имя_Массива), то есть требуется лишь имя распечатываемого массива. При этом предполагается, что элементы массива относятся к типу Real. Если мы заменим тип Real на Integer, то придется исправить еще и формат вывода, убрав одну лишнюю цифру, так как формат aa[ii]:6:2 соответствует выводу вещественных чисел.

 

Локальная обработка массива

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

Пример. Дан массив a, состоящий из 10 целых чисел. Найти 1) количество нулевых; 2) сумму положительных; 3) произведение отрицательных элементов массива.

Program Lokal;

Uses Crt;

Const n=10;

Type Massive = array [1..n] of integer;

Const a: Massive = (-4,3,-9,0,2,-1,6,0,-5,1);

Var i,p :byte; s,t : integer;

Begin

ClrScr;

p:=0; s:=0; t:=1; {Стандарты сумм и произведения}

For i:=1 to n do Begin

If (a[i]=0) Then Inc(p)

Else If(a[i]>0) Then s:=s+a[i]

Else t:=t*a[i];

End;

Writeln(‘p=’,p, ’ s=’,s,’ ‘ t=’,t);

Repeat Until KeyPressed; End.

 

Пример: Найти max и min элементы одномерного массива целых чисел и их индексы

Program Poisk;

Uses crt;

Var A:array[1..10] of integer;

i,q,max,min,imin,imax:integer;

begin

clrscr;

write ('q='); readln(q) ; {загрузка одномерного массива целых чисел}

randomize;

for i:=l to 10 do begin

A[i]:=Random(q); {от 0 до q}

writeln('A[' , i , ']=', A[i]); end;

max:=-1000; min:=1000; {max:=-1.0e38;min:=1.0e38}

for i:=l to 10 do begin

if (A[i]>max) then begin max:=A[i]; imax:=i; end;

if (A[i]<min) then begin min:=A[i]; imin:=i; end; end;

writeln('max - A[', imax, ']=',max);

writeln ('min - A[', imin, ']=',min);

readkey

end.

 

Глобальная обработка массива

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

 

ИНВЕРСИЯ

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

 

-6 -5 -1

после инверсии превратиться в массив

-1 -5 -6

Таким образом, 1-ый элемент меняется местами с N-ым, 2-ой – с (N-1)-ым, и т.д. Можно убедиться в том, что некоторый i-ый элемент поменяется с (N+1-i)-ым. Тонкость заключается в том, что при организации цикла по всему массиву от 1 до N элементы будут дважды переставлены, то есть вернуться на свои места. Дважды инвертированный массив совпадает с исходным. Из этого следует, что цикл придется заводить до середины массива.

Если вычислять эту середину как N div 2(целая часть от деления), то возможны две ситуации: четное и нечетное количество элементов. Но выясняется, что принципиальной разницы между ними нет, так как при нечетном числе элементов (например, 9) средний элемент (с номером 5) хоть и не попадает в цикл, заведенный от 1 до 4, он просто не имеет пары для перестановки. Будучи симметричным самому себе.

Если константа n, тип Massive и процедура Swap заложены в программе, то процедура инверсии может иметь вид:

Имя файла: Inversia.pas

Procedure Inversia (Var aa:Massive);

Var ii: byte;

Begin

For ii:=1 to n div 2 do Swap (aa[ii],aa[n+1-ii]);

End;

Обратите внимание на то, что, в отличие от печати массива, процедура инверсии изменяет исходный массив, и поэтому входной параметр “aa” описан как переменная.

 

ЦИКЛИЧЕСКИЙ СДВИГ

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

-6 -5 -1

 

получится массив

-6 -5 -1

Для реализации этого алгоритма нужно в первую очередь спасти первый элемент массива, записав его во вспомогательную ячейку через r:=a[1], потом переставить элементы

For i:=1 to N-1 Do a[i]:=a[i+1]

ИЛИ

For i:=2 to N Do a[i-1]:=a[i]

и, наконец, спасенное значение записать на место последнего элемента a[N]:= r. Тогда текст процедуры:

Имя файла: Sdvig_Lt.pas

 

Procedure Sdvig_Lt (Var aa:Massive);

Var ii: byte; rr: real;

Begin

rr:=aa[1];

For ii:=1 to n-1 do a[ii]:=aa[ii+1];

aa[n]:=rr;

End;

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

For i:=1 to 3 do Sdvig_Lt (a);

из исходного массива будет получен массив

-5 -1 -6

При Циклическом Сдвиге Вправо массив

-6 -5 -1

получается из исходного чуть иным путем. Убедитесь самостоятельно, что алгоритм

r:=a[N];

For i:=2 to N do a[i]:=a[i-1];

a[N]:=r;

Не приводит к цели, а текст процедур должен иметь вид:

 

Имя файла: Sdvig_Rt.pas

Procedure Sdvig_Rt (Var aa:Massive);

Var ii: byte; rr: real;

Begin

rr:=aa[n];

For ii:=n downto 2 do a[ii]:=aa[ii-1];

aa[1]:=rr;

End;

 

Вычисление среднее арифметическое, среднее геометрическое, среднее квадратичное среднее гармоническое

Иногда в задачах требуется вычислить некоторые характеристики массива. Пусть b[i] – некоторыq массив данных произвольного (но числового!) типа. Тогда для набора b[1],b[2],…,b[k] определены:

 

среднее арифметическое:

 

среднее геометрическое:

 

среднее квадратичное:

 

среднее гармоническое:

 

 

Замечание 1.Для вычисления среднего гармонического потребуется выполнение условия b[i]<>0.

Замечание 2. Для вычисления среднего геометрического необходимо, чтобы произведение, которое должно возводиться в степень 1/k, было положительно.

 

Сортировка массива

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

Пример:

При сортировке исходный массив

 

-7 -5 -1

 

по возрастанию превратится в

 

-7 -5 -1

 

по убыванию превратится в

-1 -5 -7

 

Сортировка одномерного массива методом пузырька

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

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

 

1. Преподаватель двигается вдоль шеренги слева направо.

2. Если левый студент в паре, ниже правого, преподаватель меняет их местами и переходит к следующей паре.

 

Рассмотрим в качестве примера массив

 

 

И разработаем алгоритм для обработки такого массива, тем более он подойдет и для массива, где ряд элементов уже стоит на своих местах

 

Массив перед сортировкой
      1-ый проход вдоль шеренги преподавателя (k=1)
       
      Номер левого элемента в паре меняется
      от 1-го до 4-го (i=1..4)
Массив после 1-го прохода. Один элемент занял свое место
       
      2-ой проход вдоль шеренги преподавателя физкультуры
      k=2, i=1..3
Массив после второго прохода. Два элемента заняли свои места
       
      3-ий проход (k=3, i=1..2)
Массив после 3-го прохода.
      4-ый проход (k=4, i=1)
Сортировка массива завершена.

Для 5-ти элементов массива понадобилось четыре прохода (т.е. N-1). При этом номер левого элемента в пара от прохода к проходу менялся от 1 до N-K (где К –номер прохода). Исходя, из этого напишем текст процедуры сортировки массива по убыванию элементов:

(Имя файлa: Sort_Dec.pas)

Procedure Sort_Dec(Var aa:Massive);

Var ii,kk:byte;

Begin

For kk:=1 to n-1 Do Begin

For ii:=1 to n-kk Do Begin

If (aa[ii]<aa[ii+1]) Then Begin

Swap (aa[ii],a[ii+1]);

End;

End;

End;

End;

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



<== предыдущая лекция | следующая лекция ==>
Основной блок программы | Обобщённая структурная схема ИИС


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.148 сек.