Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

CASEвыражение OF 1 страница



список значений: оператор / блок

..................................

список значений: оператор / блок

[; ELSE оператор / блок ]

END;

Здесь выражение - это любое выражение порядкового типа, список значений - это список разделенных запятыми константных выражений или диапазонов, диапазон - это конструкция вида константное выражение .. константное выражение. Константным будем называть любое выражение, в которое входят только неименованные и нетипизированные константы (т.е. в константное выражение не могут входить имена переменных, функции и типизированные константы). На самом деле константные выражения - это выражения, которые могут быть вычислены до выполнения программы, а отсюда уже и вытекают ограничения на их вид. Выражение, стоящее после CASE, и все константные выражения должны быть одного типа либо все иметь целочисленные типы. Обратите внимание, что в операторе выбора перед ELSE "; " может стоять в отличие от условного оператора.

Оператор выбора выполняется следующим образом: вычисляется выражение, стоящее после CASE, затем просматриваются все списки значений, и если значение выражения попало в список значений, выполняется соответствующий оператор или блок, и выполнение оператора CASE заканчивается. Если значение выражения не содержится ни в одном из списков, то выполняется оператор или блок, стоящий после ELSE. Конструкция ELSE может отсутствовать, в этом случае оператор CASE может не выполнить никаких действий. В качестве примера использования оператора выбора решим предыдущую задачу о правильной дате.

var d,m: byte; y: word; valid: boolean;

begin write('введите дату '); read(d,m,y);

case m of

1,3,5,7,8,10,12: case d of

1..31: valid:=true

else valid:=false

end;

4,6,9,11: case d of

1..30: valid:=true

else valid:=false

end;

2: case d of

1..28: valid:=true;

29: valid:=(y mod 4=0)and(y mod 100>0);

else valid:=false

end;

else valid:=false;

end;

if valid

then writeln('дата верна')

else writeln('дата неверна');

end.

Вы можете видеть, что задачи такого типа решаются оператором CASE гораздо проще, чем оператором IF.

Решим еще одну задачу: определить, какое число, меньшее 1000, введено пользователем.

var N:Word;

begin writeln('Введите натуральное число N<1000');

readln(N);

case N of

0..9: writeln('однозначное');

10..99: writeln('двузначное');

100..999: writeln('трехзначное')

else writeln('Число "N" не входит в указанный диапазон')

end;

readln;

end.

11. Операторы цикла

Для реализации циклических алгоритмов, т.е. алгоритмов, содержащих многократно повторяющиеся одинаковые операции, применяются специальные операторы цикла. В Паскале есть три вида циклов: FOR, WHILE и REPEAT. Оператор цикла FOR записывается в виде:

FOR переменная := начальное значение TO конечное значение DO

оператор / блок

или

FOR переменная:=начальное значение DOWNTO конечное значение DO

оператор / блок.

Здесь переменная - любая переменная порядкового типа, называемая в таком контексте переменной цикла, начальное значение и конечное значение - выражения того же типа. Цикл FOR выполняется следующим образом: переменной цикла присваивается начальное значение, после чего выполняется тело цикла (оператор или блок, стоящий после DO). Два этих действия вместе составляют один шаг цикла. Затем переменной цикла присваивается следующее (в цикле FOR... TO) или предыдущее (в цикле FOR... DOWNTO) значение и выполняется следующий шаг цикла. Так происходит до тех пор, пока значение переменной цикла не станет больше (FOR...TO) или меньше (FOR...DOWNTO) конечного значения. Цикл FOR может не выполниться ни разу, если начальное значение больше конечного в цикле FOR...TO или меньше конечного в цикле FOR... DOWNTO. Запишем два примера использования цикла FOR: вычислим сумму квадратов натуральных чисел от 1 до N:

var i: word; s:single;

const n = 22;

begin

s:=0;

for i:=1 to n do

s:=s+sqr(i);

writeln('сумма=',s:8:2);

end.

Теперь выведем на экран символы с номерами от 32 до 255:

var c: char;

begin for c:=' ' to #255 do

write(c,' ');

writeln;

end.

Второй тип цикла - цикл WHILE - записывается в виде:

WHILE логическое выражение DO оператор / блок

Здесь логическое выражение - любое выражение типа Boolean. Цикл выполняется следующим образом: вычисляется логическое выражение и, если оно истинно, выполняется тело цикла, в противном случае цикл заканчивается. Очевидно, что цикл WHILE может как не выполниться ни разу, так и выполняться бесконечное количество раз (в последнем случае говорят, что программа зациклилась). Запишем две предыдущие задачи, используя цикл WHILE:

const n = 22; var i: word; s: single; begin i:=1; s:=0; while i<=n do begin s:=s+sqr(i); inc(i); end; writeln('сумма=',s:8:2); end. var c: char; begin c:=pred(' '); while c<#255 do begin c:=succ(c); write(c,' '); end; writeln; end.

В качестве упражнения, подумайте, почему программа

var c: char;

begin c:=' ';

while c<=#255 do

begin write(c);

c:=succ(c);

end;

writeln;

end.

оказывается зацикленной.

Третий тип цикла - REPEAT -записывается в виде:

REPEAT операторы UNTIL логическое выражение;

Если тело цикла REPEAT содержит больше одного оператора, нет необходимости использовать блок, поскольку сами ключевые слова REPEAT и UNTIL являются в данном случае логическими скобками. Перед UNTIL можно не ставить "; ". Цикл REPEAT выполняется так: сначала выполняется тело цикла, затем вычисляется логическое выражение, и если оно истинно, цикл заканчивается. Таким образом, цикл REPEAT всегда выполняется хотя бы один раз. Обратите внимание на то, что тело цикла WHILE выполняется до тех пор, пока логическое выражение истинно, а тело цикла REPEAT - пока логическое выражение ложно. Запишем наши примеры, используя цикл REPEAT:

const n = 22; var i: word; s: single; begin i:=1; s:=0; repeat s:=s+sqr(i); inc(i) until i>n; writeln('сумма=',s); end. var c: char; begin c:=pred(' '); repeat c:=succ(c); write(c) until c=#255; writeln; end.

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

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

const parol='tdf25';

var i:integer;

s:string;

begin for i:= 1 to 3 do

begin

write('введите пароль'); readln(s);

if s = parol

then break

else if i <> 3 then continue;

writeln('доступ к программе запрещен');

writeln('нажмите enter');

readln;

halt

end;

writeln('пароль верен, доступ к программе разрешен'); readln;

end.

Рассмотрим еще несколько примеров.

Пример нахождения суммы бесконечного ряда

var i: Integer;

eps, sum, znam, slag: Extended;

begin

writeln(Rus('Ведите необходимую точность вычислений'));

readln(eps);

Sum:=1; znam:=1; i:=1;

repeat

slag:=1/znam;

Sum:=Sum+slag;

inc(i);

znam:=znam*i;

until slag<eps;

writeln(Rus('Сумма ряда = '),Sum:15:12);

writeln(Rus('Точное значение = '),exp(1):15:12);

readln;

end.

Пример нахождения суммы бесконечного функционального ряда

, где .

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

var y, sum, x, eps, a, mnog: extended;

i, m_dop: Word;

begin

writeln(Rus('Введите значение аргумента '), 'x='); readln(x);

writeln(Rus('Введите значение погрешности '), 'eps='); readln(eps);

writeln(Rus('Введите максимально допустимое количество членов

ряда')); readln(m_dop);

y:= sin(x);

i:= 0; {количество членов ряда}

a:= x; { a - первый член ряда }

Sum:= a; { Sum - первая частичная сумма ряда }

while (abs(a) > eps) and (i<=m_dop) do

begin

i:= i+1;

mnog:= -x*x/(2*i*(2*i+1));

a:= a*mnog;

Sum:= Sum+a;

end;

if i<=m_dop

then

begin writeln(Rus('Контрольное значение функции'),' sin(x)= ', y:12:8);

writeln(Rus('Приближенное значение функции = '),Sum:12:8);

writeln(Rus('при количестве членов ряда='), i);

end

else

begin writeln(Rus('Количество членов ряда превосходит максимально

допустимое'));

writeln(Rus('Требуемая точность вычислений не достигнута'));

end;

readln;

end.

Дадим краткую сравнительную характеристику циклических операторов:

      Таблица 4
  WHILE REPEAT…UNTIL FOR
Определение параметров цикла До начала цикла должны быть сделаны начальные установки переменных, управляющих условием цикла, для корректного входа в цикл Начальная установка переменной счетчика циклов до заголовка не требуется
Параметры цикла В теле цикла должны присутствовать операторы, изменяющие переменные условия так, чтобы цикл через некоторое число итераций завершился. Изменение в теле цикла значений переменных, стоящих в заголовке цикла, не разрешается
Работа цикла Цикл работает пока условие истинно (пока True) Цикл работает пока условие ложно (пока False). Количество итераций цикла неизменно и точно определяется значениями нижней и верхней границ и шага цикла
Условие завершения цикла Цикл завершается, когда условие становится ложным (до False). Цикл завершается, когда условие становится истинным (до True). Нормальный ход работы цикла может быть нарушен оператором goto или процедурами BREAK и CONTINUE
Минимальное количество выполнения тела цикла Цикл может не выполниться ни разу, если исходное значение условия при входе в цикл равно False. Цикл обязательно выполняется как минимум один раз Цикл может не выполниться ни разу, если шаг цикла будет изменять значение счетчика от нижней границы в направлении, противоположном верхней границе
Условие использования составного оператора тела цикла Если в теле цикла требуется выполнить более одного оператора, то необходимо использовать составной оператор Независимо от количества операторов в теле цикла использование составного оператора не требуется Если в теле цикла требуется выполнить более одного оператора, то необходимо использовать составной оператор

12. Метки. Оператор GOTO. Процедура Halt

Метка - это идентификатор, отмечающий определенный оператор исходного кода. Меткой может быть любой правильный идентификатор или целые числа от 0 до 9999, они могут записываться перед любым выполняемым оператором и отделяются от него двоеточием. Оператор может иметь любое количество меток. Все метки, использованные в программе, должны быть описаны в разделе описаний с ключевым словом LABEL. В одном операторе LABEL можно описать несколько меток, тогда они разделяются запятыми. Оператор безусловного перехода

GOTO метка;

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

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

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

var x: single;

begin write('введите число '); read(x);

x:=sqrt(x); write(x:5:2);

end.

Если введено отрицательное число, то в третьем операторе программы произойдет аварийное прерывание. Стремясь избежать этого, мы могли бы записать программу в виде:

var x: single;

label finish;

begin write('введите число '); read(x);

if x<0 then goto finish;

x:=sqrt(x); write(x:5:2);

finish: end.

Однако можно не использовать GOTO:

var x: single;

begin write('введите число '); read(x);

if x<0

then writeln('ошибка!')

else begin x:=sqrt(x); write(x:5:2); end;

end.

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

13. Интервальные типы данных. Оператор TYPE. Массивы

Интервальный тип - это некоторый подтип порядкового типа данных (вспомним, что порядковые типы - это ShortInt, Byte, Integer, Word, LongInt, Char и Boolean). Пусть, например, некоторая переменная в программе может принимать значения от -1 до 99. Мы могли бы описать ее как LongInt или Integer (хотя это излишне!), могли бы описать ее как ShortInt, что достаточно разумно. Но можно создать для нее и специальный тип данных, объединяющий только числа от -1 до 99:

var x: -1..99;

Вместо имени одного из стандартных типов мы использовали в описании переменной построенный нами собственный интервальный тип. Таким образом, описанная переменная x может принимать только значения -1, 0, 1,..., 99, в остальном она ничем не отличается от других целых переменных. Ее можно вводить, выводить, использовать в качестве переменной цикла, подставлять в выражения и т.п. Любой интервальный тип есть подтип некоторого стандартного базового типа, в нашем случае - типа ShortInt. Но если бы мы стали использовать интервальный тип - 1..200, то он бы уже был подтипом типа Integer, а 0..200 -подтипом типа Byte. Компилятор Паскаля самостоятельно анализирует интервальные типы и подбирает для них минимальный подходящий базовый тип. Это нужно знать, чтобы определять размер и способ кодировки ваших переменных. Вы можете выполнить оператор

write('переменная x:-1..99 занимает ',sizeof(x),' байт');

и убедиться, что ее размер действительно равен 1.

В качестве базового типа можно использовать не только арифметические типы, но и типы Char и Boolean (правда, в последнем случае это довольно бессмысленно). Опишем, например, переменную, значением которой могут быть только маленькие латинские буквы:

var letter: 'a'..'z';

В общем случае интервальный тип описывается как

константное выражение 1 .. константное выражение 2

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

TYPE имя типа = описание типа;

Операторы TYPE так же, как и все другие операторы описания, записываются в разделе описаний. В программе может быть сколько угодно операторов TYPE, и их можно чередовать с другими операторами описания, но любые идентификаторы, использованные в описании типа, должны быть описаны раньше. После того, как некоторый тип получил имя, вы в дальнейшем можете пользоваться этим именем вместо полного описания типа: const tmin=-5;

tmax=15; type t_range_type=tmin..tmax;

var t:t_range_type;

type t_range_subtype=tmin+3..tmax-5;

var t1:t_range_subtype;

Заметим, что хорошим тоном в программировании считается всегда давать мнемонические имена объявляемым типам.

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

ARRAY [ тип индекса ] OF тип элемента

Здесь тип индекса - ShortInt, Byte, Char, Boolean или интервальный тип; тип элемента - любой тип, в том числе и массив. Вы заметили, что не все порядковые типы можно использовать как тип индекса, это не значит, что, например, тип Word чем-то хуже типа Byte. Такое ограничение обусловлено тем, что в Паскале никакой объект не может иметь размер больше (64К - 2) байта, или 65534 байта. Это ограничение действует и для интервальных типов, так вы можете описать массив var a: array[1..65534] of byte; но не массив var a: array[1..65535] of byte; и не массив var a: array[1..33000] of word;

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

var a: array[char] of 1..5;

- массив из 256 элементов, каждый из которых есть целое число от 1 до 5, индексы элементов изменяются от #0 до #255;

const max = 99; min = 10;

type nums = min..max;

type arraytype = array[-10..0] of nums;

var a: arraytype;

- массив из 11 элементов с индексами от -10 до 0, каждый элемент - целое положительное число из двух цифр;

type indextype = 'a'..'z';

var a: array [indextype] of boolean;

- массив из 26 элементов с индексами от 'a' до 'z', каждый элемент - логическая переменная.

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

имя массива [ индексное выражение ]

Индексное выражение - это любое выражение соответствующего типа. Если элемент массива - не массив, то с ним можно выполнять любые операции, разрешенные для простых переменных соответствующего типа. Целому массиву можно лишь присваивать массив того же типа. Заметим, что если массивы описаны в программе таким образом:

var a: array[1..3] of single;

b,c,d: array[1..3] of single;

type massiv=array[1..3] of single;

var e,f: massiv;

g: massiv;

h,i: massiv;

то массивы b, c, d - однотипные и массивы e, f, g, h, i тоже однотипные, но массивы a и b (a и c, a и d) имеют разный тип; и массивы b (c, d, a) и e (f, g, h, i) тоже имеют разный тип! Компилятор считает, что две переменные имеют один и тот же тип, только если они описаны в одном операторе через запятую, либо имена их типов одинаковы! Запомните это очень важное правило.

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

const Nmax=100;

type IndexType = 1..Nmax;

Mas = array [IndexType] of integer;

var i,dim:1..100;

a,b,c:Mas;

N,j,k:Byte;

S,a_max:Integer;

begin

repeat

writeln('Введите размерность массива от 1 до ',Nmax);

readln(dim)

until (dim>=1) and (dim<=Nmax);

repeat

writeln('Заполнить массив вручную (1) или случайным образом (2)?);

readln(N)

until (N<>1) or (N<>2);

if N=1

then for i:= 1 to dim do

begin write(' Введите A[ ', i, ' ] = ');

readln(a[i])

end

else begin randomize;

for i:= 1 to dim do

a[i]:= - 30 + Random(71);

end;

writeln; writeln('Массив А');

for i:=1 to dim do

write(a[i]:3,' ');

writeln;

s:= 0;

for i:= 1 to dim do

s:= s + a[i];

writeln('Сумма элементов массива = ',S);

a_max:= a[1];

for i:= 1 to 100 do

if a[i] > a_max

then

begin a_max:= a[i];

j:= i

end;

writeln('Наибольший элемент массива a[',j,']= ',a_max);

j:= 0; k:= 0;

for i:=1 to dim do

if a[i] >= 0

then begin j:= j+1;

b[j]:= a[i]

end

else begin k:= k+1;

c[k]:= a[i]

end;

writeln('Cоздание новых массивов с элементами: b[j] >=0, c[k] <0');

writeln('Массив b:');

if j>0

then for i:=1 to j do write(b[i]:3,' ')

else

writeln('массив не содержит элементов');

writeln; writeln(('Массив c:');

if k>0

then for i:=1 to k do write(c[i]:3,' ')

else writeln(Rus('массив не содержит элементов'));

writeln; readln

end.

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

var a: array[1..10] of array[1..20] of single;

или так:

var a: array[1..10, 1..20] of single;

При обращении к ячейкам массиваможно использовать в программе запись вида a[i][j] или a[i,j].

Напишем программу, перемножающую две квадратные вещественные матрицы:

const Nmax=100;

type IndexType = 1..Nmax;

Mas = array [IndexType] of integer;

Mas_d = array [IndexType,IndexType] of integer;

var a,c: Mas_d;

ss,b: Mas;

N,m,a1,i,j,dim,l: Integer;

begin

repeat

writeln('Введите размерность массива от 1 до ',Nmax-1);

readln(dim)

until (dim>=1) and (dim<Nmax);

repeat

writeln('Заполнить массив вручную (1) или случ образом (2)?);

readln(N)

until (N<>1) or (N<>2);

if N=1

then for i:= 1 to dim do

for j:=1 to dim do

begin write(' Введите A[ ', i, ',',j,' ] = ');

readln(a[i,j])

end

else

begin randomize;

for i:= 1 to dim do

for j:=1 to dim do

a[i,j]:= - 30 + Random(71);

end;

writeln;

writeln('Массив А');

for i:=1 to dim do

begin for j:=1 to dim do

write(a[i,j]:3,' ');

writeln;

end;

for i:= 1 to dim do

begin SS[i]:= 0;

for j:= 1 to dim do

SS[i]:= SS[i] + A[i, j];

writeln('Сумма элементов ',i,' строки = ',SS[i]);

end;

readln;

writeln('Обмен местами первой и последней строки');

for j:= 1 to dim do

begin a1:=a[1,j];

a[1,j]:=a[dim,j];

a[dim,j]:=a1

end;

writeln('Измененный массив А');

for i:=1 to dim do

begin for j:=1 to dim do

write(a[i,j]:3,' ');

writeln;

end;

readln;

repeat writeln('Введите номер столбца (от 1 до ',dim,')');

readln(M)

until (m>=1) and (m<=dim);

writeln('Вставка данных из одномерного массива B в столбец с

номером ', M,' массива А'); writeln('Массив B');





Дата публикования: 2014-11-04; Прочитано: 343 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.064 с)...