лекции (2008) (Фингеров Александр_ Кононов Алексей_ Кузин Сергей), страница 7
Описание файла
Документ из архива "лекции (2008) (Фингеров Александр_ Кононов Алексей_ Кузин Сергей)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "лекции (2008) (Фингеров Александр_ Кононов Алексей_ Кузин Сергей)"
Текст 7 страницы из документа "лекции (2008) (Фингеров Александр_ Кононов Алексей_ Кузин Сергей)"
I=0;
WHILE (A[I]<>X) and (I<N) DO InC(I) END
здесь есть существенная ошибка – Модула 2 и Оберон – языки с квазистатическим контролем, произойдёт выход за границу массива. Операции нужно переставить. Именно для логических операций иногда имеет смысл зафиксировать так называемую ленивость вычислений, точно так же как 0 and X =0 и 1 or X = 1. В языке Ада было принято решение ввести логические операции and then и or else. Однако если мы программируем без побочных эффектов, то нам всё равно в какой последовательности вычисляется выражение, но запретить их можно отнюдь не во всех языках. Эволюция состоит в том, что вначале под понятием потока управления подразумевали произвольную передачу управления в любую точку программы с помощью оператора GOTO, программисты рисовали блок-схемы и умели переводить их в двоичный код. С появлением Фортрана математики стали программистами, а ситуация начала меняться, когда стали писаться более сложные программы – например ОС. В 1967 году Э.Дейкстра опубликовал свою статью о вредности оператора GOTO, это была революционная статья. В языке Фортран было 4 разновидности оператора GOTO, программистам старались давать как можно больше возможностей. Основная мысль Дейкстры заключалась в том, что производительность может вырасти, когда эти возможности ограничены, но повышается уровень осознания того, что пишет человек. Иначе говоря, появилось понятие «структура управления». Если таких абстракций нет, то их нужно моделировать. Идея программирования состоит не просто в изобретении алгоритма или его записи, а собственно в «изобретении». Мы имеем задачу и её реализовываем. Фактически статья дала начало дисциплине «Технологии Программирования». В 1968 году появились статья «Заметки о структурном программирование», что более корректно перевести как «Структурированное программирование», и статья о сопрограммах. В 1966 году была доказана теорема, что любую операторную схему можно реализовать с помощью операторов последования, присваивания и цикла while B do S. Теоретический базис был заложен. И язык С и Паскаль восприняли идею Дейкстры.
Альтернативы GOTO:
- циклы
- ветвления (употребление условного оператора)
- составной оператор (или блок)
В АЛГОЛе не заметили синтаксическую проблему if B then if B1 then S1 else S2. Программисты обычно выделяют структуру отступами. Здесь возможно 2 варианта – либо первый оператор укороченный, а второй – двусторонний, либо наоборот. В большинстве ЯП сами по себе отступы значения не имеют, и требовалось решение. Оно появилось - else прикреплялся к ближайшему if. Если мы хотим сделать 2й вариант – необходимо ставить скобки begin-end. Альтернатива была реализована в новом семействе языков – Ада, Модула 2, Оберон, Visual Basic. Отказались от понятия составного оператора, каждый оператор явно замыкался. Проблемы этого пути обсудим на следующем занятии…
Лекция №15 и №16
Глава 3. Управление последовательностью действий.
Ветвление и цикл.
Оператор if:
If B1 then
If B2 then
S2
Else
S3
Else относится к ближайшему if.
Если мы хотим по-другому, то надо использовать составной оператор (блок). В Паскале есть понятие составного оператора и блока. Существенное отличие заключается в области видимости: блок – составляет область видимости, а в составном операторе нет области видимости.
В Аде есть понятие составного оператора.
Например, чтобы в Алголе написать else ко второму if надо написать так :
If
Begin
If …
End
Else
Языки Ада, Модула-2, B-Shell, Оберон – в которых любой оператор явным образом закрывается. Теперь проблема вложенности решается так:
В Аде:
If B then
S1;S12;S13;…
End if (нет оператора end, обязательно должно что-то следовать после)
Оберон:
IF B THEN
Seq1
ELSE
Seq2
END
B-Shell:
If
..
fi
Решение всегда закрывать операторы if. Что плохо? Выбор двух развилок наиболее часто встречающаяся конструкция. В некоторых случаях нужно многовариантное ветвление.
Условие выполнения B1;B2;,…BN соотносится соответственно к S1, S2,…SN.
If B1 then
S1
Else
If B2 then
S2
Else
If B3 then
S3
Психологи говорят, что человеку сложно осознать эту конструкцию. Наиболее удобная структура следующая
If B1 then S1;
If B2 then S2;
Опытные программисты используют следующую запись: (Си)
If (B1)
S1;
Else if (B2)
S2;
Else if (B3)
S3;
Else
SN+1;
Случай дискретного выбора.
Условие Bi сводится к варианту expr = ci;
Для этих случаев используется оператор выбора (переключатель).
В паскале:
Case Expr of
Список вариантов
End
Вариант имеет вид:
Const: operator;
Что будет, если значение выражения не попадает ни в один вариант? Это не учтено в Паскале. В Турбо Паскале добавили вариант else operator;
В Модуле-2 :
CASE EXPR OF
СПИСОК ВАРИАНТОВ ЧЕРЕЗ СИМВОЛ ‘|’
ELSE
ОПЕРАТОРЫ
END
В Модула-2 возможно:
Const: operator
Const1..const2
1,3,5,…,10,12:
В Аде:
Case Expr of
{when список констант или диапазонов => оператор}
[When other => операторы]
End case;
{} – несколько (от 0 и более)
[] – необязательно
В Си:
Switch (expr){
Case const:
сase 0: case1: case2: оператор; break; }
Это обычные операторы GOTO. Если не поставить break; , то выполнение продолжиться дальше и будет выполняться до break; или конца switch().
В языке Java все тоже самое, и самое смешное – там нет оператора перехода, а в переключателе он торчит х).
В Си Шарп break; надо писать, а если не написал, то компилятор выдаст ошибку.
Также есть вариант
default: операторы; break;
Структура операторов цикла.
В Паскале впервые был реализован стандартный набор, который включал в себя:
If, case
While B do S
Repeat S1; .. Sn; until B;
For (это частный случай, который сводится к while)
Структурное программирование: структура программы должна соответствовать структуре программирования.
Пример цикла:
-
Подготовить ввод
-
Если удался, то выполнить обработку и найти на подготовку ввода,
2.1) Если нет, то выходим.
Если программировать с помощью while:
-
Подготовить.
-
While на условие, если да – обработка и дублирование блока подготовки, если нет – то вылетаем.
Это не структурное программирование, так как не соответствуют структуре алгоритма.
Модула-2
WHILE B DO … END
REPEAT … UNTIL B;
LOOP .. END (бесконечный цикл, нужен в параллельном программировании). Выйти можно, если только сделать EXIT.
IF B THEN .. EXIT;
Если выход из середины, то используйте только цикл LOOP, из циклов while и repeat нельзя выходить из середины.
В Аде:
While B loop
..
End loop;
For ..
Loop .. end loop;
Но нет repeat.
Есть оператор exit.
Укороченная форма – exit – выход из цикла.
Допустима вторая форма
when условие => exit;
Если последнюю форму поставить перед end loop, то получим оператор repeat.
В Си:
While (B) S
Do S while (B);
For
S – блок.
Есть операторы break; и continue;. Break – оператор выхода из любого места, а continue; - продолжение цикла.
Оператор return[exr]; в Си, Аде, Модула-2, Оберон, Java, C# - выход из функции, который необязательно символизирует, что мы вышли из процедуры корректно.
Goto нет в Mодула-2, Java, Обероне.
Выход из ситуации:
Имя:
Цикл или переключение
Break имя; - выходит из нужного вами цикла.
Нельзя по goto выйти за пределы функции или процедуры, в которой он находится.
Цикл for.
Появился в Алголе-60. В этом языке операторов цикла было больше чем в Паскале.
В Паскале форма цикла:
For v:= e1 to e2 do S. (или вместо to использовать downto)
В Модуле-2:
FOR V:= E1 TO E2 [STEP E3 (целое значение)] DO .. END;
E3 мог иметь положительный знак или отрицательный. E1 и E2 – типы, к которым применима операция сложения или вычитания.
В 1993 году в Обероне-2 вернули цикл for в том виде, в котором он был в Модуле-2. Этот оператор не был излишним, раз он вернулся в Оберон-2.
For v in диапазон loop
End loop;
For i in A'RANGE loop S:=S+A(i); end loop; (или in reverse для обратного порядка)
For i in A’FIRST..A’LAST loop S:= S +A(i); end loop;
В Аде i локализована внутри цикла.
В Си: For (e1; e2; e3)
А бесконечный цикл можно представить следующим способом: for (;;) S.
E3 выполняется каждый раз в конце цикла.
For (int i=0; i<N; i++) S
В java, C#
В операции S+=A[i] - осуществляется квазистатический контроль, что замедляет выполнение работы программы.
Глава 4. Процедурные абстракции в ЯП.
Процедурные абстракции с точки зрения:
-
Потока управления (control flow) – передача управления
-
Потока данных (data flow) – передача параметров
Процедурные типы данных.
Пункт 1. Передача управления в ПА. Подпрограммы и сопрограммы.
Всегда один вход (оператор Call P) и один выход (Return). Оператор возврата есть не во всех ЯП и может быть в самых разных частях программы. Оператор return – обобщение оператора break. Таким образом, все операторы return переходят (goto) в конец процедуры.
В языке Фортран была конструкция ENTRY, которая позволяла войти в любую часть процедуры. То есть процедуры имели несколько входов. Так же была возможность иметь несколько выходов.
SUBROUTINE P(N, *) - подпрограмма
Тогда, например, call P(N, 25).
Были попытки определить дополнительные точки входа и выхода в процедуру, то есть была возможность входить в процедуру не с начала и возвращать управление не в точку выхода.
С точки зрения передачи управления мы видим, четкая не симметрия между вызывающей программой и вызываемой. В Алголе-60 процедуры и функции – подпрограммы соответственно не возвращающие и возвращающие значение.
Выполнение подпрограммы всегда происходит с точки входа, а возврат происходит в точку вызова. Такая конструкция была предложена в середине 60-х годов.
Альтернативный вариант – переход от понятие subroutine к coroutine, то есть работа нескольких параллельно работающих программ. Это некоторый аналог механизма параллельных процессов. При повторном входе в подпрограмму вход будет в ту точку, из который был выход при прошлом обращении к ней.
COROUTINE – сопрограмма
В Модуле-2: