Редактирование: Языки программирования, 12 лекция (от 12 октября)

Материал из eSyr's wiki.

Перейти к: навигация, поиск

Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.

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

Текущая версия Ваш текст
Строка 1: Строка 1:
-
[[Языки программирования, 11 лекция (от 10 октября)|Предыдущая лекция]] | [[Языки программирования, 13 лекция (от 17 октября)|Следующая лекция]]
+
== From Ebaums Inc to MurkLoar. ==
-
 
+
We at EbaumsWorld consider you as disgrace of human race.
-
= Часть 1. Основные понятия традиционных процедурных ЯП =
+
Your faggotry level exceeded any imaginable levels, and therefore we have to inform you that your pitiful resourse should be annihilated.
-
== Глава 3. Операторный базис ЯП ==
+
Dig yourself a grave - you will need it.
-
 
+
-
<div class="comment">В терминологии полный бардак. Нет согласия, как переводить computer science. Начиная с 60х годов, то, что слово &laquo;statement&raquo;, в описании языка [[Algol|Algol 60]], стало эталоном языкового описания. &laquo;Assignment statement&raquo;&nbsp;&mdash; оператор присваивания. В русском языке появилась традиция переводить слово &laquo;statement&raquo; как &laquo;оператор&raquo;. Иногда ещё употребляется термин &laquo;инструкция&raquo;. Мы будем употреблять термин &laquo;оператор&raquo;. Проблема в чём: проблем нет, есть оператор, есть операция (сложение, вычитание). Проблема была порождена [[C++]], где под оператором понимали то, что мы понимаем под словом операция. Есть переопределение операций.
+
-
 
+
-
В терминологии главное договориться. Мы будем следовать традициям [[Algol|Algol 60]] и под оператором будем понимать statement, операция&nbsp;&mdash; это операция.</div>
+
-
 
+
-
'''Операторный базис ЯП'''&nbsp;&mdash; то, какие операторы есть в ЯП.
+
-
 
+
-
<div class="comment">Операторный базис унифицирован больше всего. Причина историческая.</div>
+
-
 
+
-
=== Пункт 1. Структурное программирование ===
+
-
 
+
-
<div class="comment">Кто-то отмечал, что strcutured programming переводится как структурированное программирование.</div>
+
-
 
+
-
История начинатся в [[1961]] году, когда ныне покойный Дейкстра опубликовал статью о вреде языка goto. Идея (казалось бы, бредовая): необходимо ограничитиь программиста в управлении, то есть, ограничеть возможности по управлению выполннием программы. Кажущаяся бредовость заключается в том, что до этого цель разработчика языка программирования дать как можно больше возможностей программисту.
+
-
 
+
-
<div class="comment">Ограничение возможностей программиста влияет благотворно.</div>
+
-
 
+
-
В [[Java]] нет goto. Но в Java он зарезервировано, чтобы изгнать это &laquo;слово из четырёх букв&raquo;.
+
-
 
+
-
Разбиение операций на приватные и публичние тоже ограничение возможностей программиста.
+
-
 
+
-
Ситуация, когда програмиста ограничивают в выразительных возможностях иногда полезна.
+
-
 
+
-
Структурное программирование вредно представлять как программирование без goto. Это программирование в терминах уровней абстракций.
+
-
 
+
-
Есть три блока:
+
-
# Подготовить
+
-
# Выполнить
+
-
# Завершить
+
-
 
+
-
Потом понижаем уровень абстракции до конкретных языках языка программирования, и операторы языка программирования&nbsp;&mdash; чёрные ящики.
+
-
 
+
-
Идея оказалась благотворной.
+
-
 
+
-
Довольно быстро все пришли к консенсусу, что структурное программирование полезно.
+
-
 
+
-
Современных программитстов обучают таким образом, что они программируют в терминах структурного программирования.
+
-
 
+
-
<div class="comment">Любимый пример лектора из опыта военной подготовки:<br />
+
-
Читали там на [[Algol-60]]. Была программа, которую написал майор. Программа генерации перестановок. Сама по себе задача выеденного яйца не стоит. Проблема в том, что рекурсия не употреблялась, но там где-то на 9 строчек было 7 операций goto. Ив течении половины лекции пытался объяснить, как она работает, и в итоге сказал «даю вам слово, это программа работает. Я её полночи проверял».</div>
+
-
 
+
-
Программы с интенсивным использованием goto стали называтьм ​DS-программы (dish of spagetti).
+
-
 
+
-
Самый главный оператор&nbsp;&mdash; оператор присваивания. Самое интересное с операторе присваивания&nbsp;&mdash; согласование типов, а это уже ТД.
+
-
 
+
-
Основные операторы классифицируются на несколько видов:
+
-
# Оператор присваивания
+
-
# Управляющий оператор
+
-
# Специальные операторы
+
-
В современных языках оитсустствуют такие вещи, как операторы ввода-вывода.
+
-
 
+
-
Существенно оказало влияние то, какие существуют операторы управления.
+
-
 
+
-
# Операторы ветвления. Делятся на
+
-
## Ветвления
+
-
## Дискретные
+
-
## Многовариантные
+
-
# Циклы
+
-
## С предусловием
+
-
## С постусловием
+
-
## С фиксированны числом повторений
+
-
## С управлением пользователем
+
-
# Переходы
+
-
# Блок
+
-
 
+
-
Переходов очень много вариантов.
+
-
 
+
-
А можно обойтись без goto?
+
-
 
+
-
Была опубликована статья: любую управляющую структуру можно свести к трём, точнее, двум структурам&nbsp;&mdash; цикл и последовательность (третья структура, условие&nbsp;&mdash; цикл не более чем с одной операцией)
+
-
 
+
-
Более того&nbsp;&mdash; программы с любыми комбинациями условий можно свести к композициями циклов. Создавались программы, которые позволяли переводить программы с goto в программы без goto.
+
-
 
+
-
В ... году ехидный Кнут написал статью «структурное программирование с использованием goto». Знаменитая цитата: «иногда употребелние всяких слов из четырёх букв типа goto является уместном даже в самом лучшем обществе».
+
-
 
+
-
=== Пункт 2. Ветвление ===
+
-
 
+
-
==== Двухвариантное ветвление ====
+
-
 
+
-
'''([[Algol]])'''
+
-
'''([[Pascal]])'''
+
-
if B then
+
-
S1
+
-
else
+
-
S2
+
-
 
+
-
Отличаются ЯП по тому, стоавить then или нет, ставить скобки или нет. ЯП с точки зрения управляющих конструкций делятся на две категории&nbsp;&mdash; с терминаторами и без терминаторов. В ЯП без терминаторов&nbsp;&mdash; неявное завершение условия.
+
-
 
+
-
Проблема, которую заметил Дональд Кнут:
+
-
 
+
-
if B1 then if B2 then S1 else S2
+
-
 
+
-
Вопрос, когда выполняется S2, к какому if прижимается else. Более того, в первой реализации [[Algol-60]] эту проблему просмотрели, а Кнут её первый заметил.
+
-
 
+
-
В языках без терминаторов нужно использовать составные операторы (&laquo;begin&nbsp;&hellip;&nbsp;end&raquo;, &laquo;{&nbsp;&hellip;&nbsp;}&raquo;)
+
-
 
+
-
В языках с явными терминаторами явно обозначается конец. Примеры&nbsp;&mdash; [[Ada]], [[Modula-2]], [[Oberon]]. В этих языках отсутствует понятие составного языка как такового.
+
-
 
+
-
if B then S1 else S2 end if;
+
-
 
+
-
<!-- Бейсик тоже удовлетворяет. - ??? -->
+
-
 
+
-
Такие языки синтаксически более элегантны. Проблема языков с неявными операторами в том, что в том месте, где пропущена скобка, возникают вложенные операторы. В ЯП с явным терминатором синтаксический анализ проводить проще, и ошибки искать проще. Но тут сразу возникает другая проблема.
+
-
 
+
-
==== Многовариантное ветвление ====
+
-
 
+
-
Есть несколько вариантов, частным случаем которого является дискретное ветвление. В общем случае с каждым оператором связано своё условие. В некоторых ЯП (например, в Ada) есть оператор select:
+
-
 
+
-
'''([[Ada]])'''
+
-
select
+
-
when B1 => S1
+
-
when B2 => S2
+
-
...
+
-
when Bn => Sn
+
-
else Sn+1;
+
-
end select;
+
-
 
+
-
В общем случае в ЯП такой структуры нет, она очень легко моделируется с помощью if:
+
-
 
+
-
if (B1)
+
-
S1
+
-
else if (B2)
+
-
S2
+
-
else if (B3)
+
-
S3
+
-
else Sn+1
+
-
 
+
-
Такой способ записи удобен для языков, где нет явного терминатора. В языках с явным терминатором надо писать в конче кучу end if. Простое синтаксическое решение ведёт к появлению специального оператора.
+
-
 
+
-
В [[Modula-2]]: ELSIF, чтобы подчеркнуть, что это не ELSE IF.
+
-
 
+
-
'''([[Ada]])'''
+
-
if B then
+
-
seg1
+
-
elseif (b2)
+
-
seg2
+
-
...
+
-
else
+
-
segn
+
-
end if;
+
-
 
+
-
Подобные конструкции должны появляться во всех языках с явным терминатором.
+
-
 
+
-
==== Дискретный оператор ветвления ====
+
-
 
+
-
Начиная с [[Pascal]] и [[C]], есть дискретное ветвление, ибо оно появляется настолько часто, что для этого появляются специальные управляющие структуры.
+
-
 
+
-
'''([[Pascal]])'''
+
-
case E of
+
-
0: seg1; { в [[Modula-2]] и [[Oberon]] вместо «;» d этом случае используется «|» }
+
-
1..3: seg2;
+
-
4, 6..9 : seg3;
+
-
else
+
-
segN;
+
-
end;
+
-
 
+
-
'''([[Ada]])'''
+
-
сase E of
+
-
when V1 => seg1 — знаков-терминаторов не нужно, ибо им будет либо следующий when, либо end
+
-
when V2 => seg2
+
-
...
+
-
when others => segN
+
-
end case
+
-
 
+
-
Этот синтаксис похож на синтакси записей с вариантами.
+
-
 
+
-
Если бы оператор переключателя отсутствовал, то это был бы миинус языка, так как он как минимум нужен для работы с записями с вариантами.
+
-
 
+
-
Опепраторы с переключателями могут быть более эффективны, чем каскад из if или select.
+
-
 
+
-
Если память не очень жалко, то можно сделать таблицу адресов переходов.
+
-
 
+
-
Единственным уроодом выглядит переключатель языка [[C]]:
+
-
 
+
-
<!-- //педедыв -->
+
-
 
+
-
<!-- Лектор: Я считаю, что университет не должен быть ангажирован, но тем не менее, я не являюсь масдащиком, и как Цезарь, преподаватель должен быть вне подозрений. -->
+
-
 
+
-
С точки зрения большинства экспертов, синтаксис [[C]] один из самых неудачных. Хуже только [[FORTRAN]]. Но, тем не менее, он окозался настолько популярным, что многие языки имеют синтаксические корни [[C]].
+
-
 
+
-
<div class="comment">На экзамене за синтаксические ошибки лектор ругать не будет.</div>
+
-
 
+
-
Синтаксис:
+
-
 
+
-
'''([[C]])'''
+
-
switch (e) S
+
-
 
+
-
Обычно S&nbsp;&mdash; составной оператор. В котором есть метки специального вида:
+
-
 
+
-
Switch(e)
+
-
{
+
-
case val:
+
-
...
+
-
default:
+
-
...
+
-
}
+
-
 
+
-
if e = val then goto val;
+
-
 
+
-
В этом уродство. Если не нашли и есть default, то goto default.
+
-
 
+
-
Проблема в том, что только один goto.
+
-
 
+
-
Основная ошибка, которую делает даже лектор, и не потому что он крутой, а потому что он 15 лет программирует на [[C]] с перерывами на [[Delphi]] и другие языки: забывание break. В некоторых случаях отсутствие break бывает необходимо, но лектор использовал её всего несколько раз, и то неправильно.
+
-
 
+
-
Языки, которые основаны на [[C]]: В [[Java]] goto нет, но идиотизм с break остался. В [[C#]] брейк писать надо, но не писать его нельзя, дабы обеспечить мобильность навыков, знаний. В [[Java]] break может содержать метку, а метка может помечать начало цикла, и это позволяет делать break более чем на один уровень.
+
-
 
+
-
После обсуждения операторного базиса отметим, что [[Pascal]] был написан Виртом, который был одним из основателей структурного программирования. Набор управляющих конструкций стандартного Pascal кочует из однго языка в другой.
+
-
 
+
-
==== Циклы ====
+
-
 
+
-
'''([[Pascal]])'''
+
-
while B do
+
-
S;
+
-
+
-
repeat
+
-
S1;
+
-
...
+
-
Sn;
+
-
until B;
+
-
 
+
-
'''([[C]])'''
+
-
while (B)
+
-
S;
+
-
+
-
do
+
-
S
+
-
while (B)
+
-
 
+
-
Мэтры согласислись, что этого достаточно, но не тут-то было. Кнут в статье «структрное программирование с goto» отметил, что структура программы должна отвечать структуре алгоритма, а он структурен, но алгоритм не всегда укладывается в while и do while.
+
-
 
+
-
Алгоритм:
+
-
* Подготовить ввод
+
-
* Если конец файла, то выйти иначе обработать и в начало.
+
-
 
+
-
Тут выход из середины цикла. Это можно смоделировать циклами до, но это корёжит структуру. Тут лучше использовать goto.
+
-
 
+
-
<div class="comment">Лектор, будучи студентом писал метакомпилятор на [[Fortran-66]] (там отсутствовал логический оператор, отсутствовали циклы, но было 4 оператора перехода), который отвечсал структурному программированию, но был на goto.</div>
+
-
 
+
-
==== Циклы, управляемые пользователем ====
+
-
 
+
-
Рассмотрим на примере языков Вирта, как являющихся минимальными.
+
-
 
+
-
Есть
+
-
 
+
-
WHILE B DO
+
-
S1
+
-
END
+
-
 
+
-
А есть
+
-
 
+
-
LOOP
+
-
S1 ... SN
+
-
END
+
-
 
+
-
В [[Modula-2]] квазипараллельное программирование: бесконечные циклы не ошибка, они иногда необходимы, например, для фоновых процессов. Только в LOOP может использоваться EXIT. EXIT то же самое, что и break в [[C]], только у него более широкое поле деятельности.
+
-
 
+
-
Наиболее универсальная концепция цикла в языке Ада:
+
-
 
+
-
'''([[Ada]])'''
+
-
loop
+
-
S1 ... Sn
+
-
end loop;
+
-
 
+
-
есть специальная конструкция:
+
-
 
+
-
'''([[Ada]])'''
+
-
[when B => ] EXIT;
+
-
 
+
-
аналог
+
-
 
+
-
'''([[Ada]])'''
+
-
if B then
+
-
exit;
+
-
end if;
+
-
 
+
-
На этот loop может навёртывается while B do, который или перед loop, или перед end loop.
+
-
 
+
-
Ещё [[BASIC]].
+
-
 
+
-
Ada позволяет с помощью одной синтаксической конструкции промоделировать любые виды циклов.
+
-
 
+
-
Языки делятся на два класса:
+
-
# C-подобные языки
+
-
# Остальные&nbsp;&mdash; те языки, которые представлены в курсе, основаны или близки к Pascal
+
-
 
+
-
[[BASIC]]:
+
-
 
+
-
'''([[C]])'''
+
-
for (e1; e2; e3)
+
-
S
+
-
 
+
-
'''([[Pascal]])'''
+
-
for i:=e1 to e2 do
+
-
S;
+
-
 
+
-
'''([[Modula|Modula-2]])'''
+
-
FOR I:=E1 TO E2 STEP E3 do
+
-
...
+
-
END;
+
-
 
+
-
[[Oberon-2]]:
+
-
 
+
-
Вирт с пафосом в design notes: Так же сочтён излишним оператор for.
+
-
 
+
-
Но возникает необходимость где-то описывать локальные переменные, которые нужны только для того, чтобы индексировать массивы и т.&nbsp;д.
+
-
 
+
-
'''([[Ada]])'''
+
-
for i in range do
+
-
loop
+
-
end loop;
+
-
 
+
-
Переменная i локализуется внутри цикла.
+
-
 
+
-
'''([[C++]])'''
+
-
for(int i=0; ...)
+
-
 
+
-
Страуструп сказал, что некоторые вещи он сделал бы по-другому.
+
-
 
+
-
Дальше всех пошли создатели [[Visula Basic]] и [[C#]]:
+
-
 
+
-
foreach (T x in C) S
+
-
 
+
-
Для массивов данный оператор не особо нужен, но тем не менее, лучше ибо в for(int i=0; i<a.length; i++) {... a[i] ...} индексация медленнее, ибо проверки, а для foreach проверки не нужны. На самом деле, в современных ЯП появляются понятия рефлексии&nbsp;&mdash; в программе могут использоваться свойства программы. В [[C#]]&nbsp;&mdash; коллекция&nbsp;&mdash; то, что поддерживает интефейсом Enumerable, и если написать свой класс, то он тоже будет коллекцией и поддерживаться foreach. Этого в [[C++]] и более старых языках не было. Другой пример рефлексии&nbsp;&mdash; атрибуты в [[C#]].
+
-
 
+
-
<div class="comment">Осталось поговорить про переходы: есть операторы, которые являются частными случаями переходов, break и continue, return. Это не противоречит основным концепциям структруного программирования.</div>
+
-
 
+
-
{{Языки Программирования}}
+
-
{{Lection-stub}}
+

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. eSyr's_wiki:Авторское право).
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!

Разделы