Лекция 08 (лекции (2002)), страница 2

2019-09-19СтудИзба

Описание файла

Файл "Лекция 08" внутри архива находится в папке "лекции (2002)". Документ из архива "лекции (2002)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Лекция 08"

Текст 2 страницы из документа "Лекция 08"

Примерно такая же ситуация стала и перед создателями языка C#, тем более, что отец языка C# одновременно и отец Турбо Паскаля, и в душе он смеялся над подобного рода конструкциями. Но тут нужна была переносимость некого стиля программирования, то есть если Сишный программист не видит в конце case break;, то у него возникает подсознательное ощущение, что его кидают. Поэтому создатели C#, оставив синтаксис очень похожим, ввели понятие «case-блока» - это последовательность операторов, которая начинается с последовательности меток, и он заканчивается либо меткой case (другой), либо меткой default, либо, соответственно, управляющей скобкой. И сказано, что коль скоро мы пишем любой case-блок, то он должен обязательно кончаться либо ключевым словом break;, либо goto case c;. С помощью этого можно было явно моделировать конструкции вроде, той, что была выше:

switch (e)

case 0:case 1:

S1;

goto case 2;

case 2:

S2;

Если мы забудем либо break, либо goto компилятор выдаёт сообщение об ошибке.

Других ветвлений в ЯП в общем-то нет, за исключением, опять же языков параллельного программирования, где есть так называемые параллельные ветвления, то есть многовариантный выбор, дело в том, что в случае последовательных ЯП здесь происходит последовательный опрос вариантов, и довольно часто некоторые компиляторы даже переключатель программируют как последовательный опрос вариантов, хотя, как ранее было сказано, здесь есть возможность вставлять оптимизацию. В Аде есть специальный оператор select, который с одной стороны можно рассматривать как многовариантный выбор, но нужно понять, что условия соответствующие как бы вычисляются параллельно, то есть по мере поступления. В данный момент мы не будем рассматривать параллельный стиль программирования.

2)Операторы цикла (наиболее используемые после операторов ветвления). В первом ЯП, как уже говорилось, было четыре оператора перехода и два оператора ветвления, которые сводились к операторам перехода. Там была всего одна форма цикла, причём достаточно уродская, которая в настоящее время из Фортрана исключена вообще. Сейчас, в современных ЯП, три вида ветвлений и четыре вида операторов цикла. Причём циклы как раз именно ветвятся, причём даже такой минимальный язык как Оберон, включает в себя весь полный набор операторов цикла. Первый классический вид цикла, который появился ещё в Паскале, и был унаследован из Алгола, хотя и сильно упрощён, это цикл «пока»: while B do S;, и цикл «до»: repeat S1;…SN until B. Аналогичного вида цикл есть и в Си, и всё различие в том, что в Паскале у нас условие выхода, а в Си, С++ и Jave это условие продолжения: do S while (B);. Но S- должен быть одним оператором, поэтому, программисты, как правило, сразу ставят составной оператор {S}.

Уже в языке Паскаль появился ещё один оператор, а именно оператор цикла со счётчиком, то есть та же самая конструкция, что с ветвлениями, не смотря на то, что дискретное ветвление- это частный случай многовариантного логического ветвления, тем не менее, во всех современных ЯП дискретное ветвление есть, просто потому, что оно очень часто встречается, а так же как возможность вставки для компилятора некоторой оптимизации. Так же и оператор цикла for: for i := e1 to e2 do S. В Модуле 2: for i := e1 to e2 step e3 do S. При этом во всех языках, основанных на Паскале, e1, e2 и e3 вычислялись сразу же, перед входом в цикл. То есть это цикл с фиксированным числом повторений. В первой версии языка Оберон подобного рода оператор был исключён, из-за его очевидной излишности (Вирт), так как тоже самое можно промоделировать с помощью цикла типа пока. В Оберон 2 его вернули, без объяснений. В языках основанных на Си семантика этого цикла различается достаточно сильно. В общем случае: for (e1;e2;e3) S;, где e3, e2 интерпретируются как логические выражения. Но отличия в том, что, во-первых, любое из этих выражений может отсутствовать, а, во-вторых, e1 вычисляется сразу, а e2 и e3 перевычисляются на каждом шагу. Поэтому в некоторых случаев реализация такого цикла for будет мене эффективна, чем соответствующая Паскалевская, Модуловская или Обероновская реализация. Хотя современные компиляторы могут распознать случаи, когда не надо перевычислять выражения на каждом шагу. В целом, семантика остаётся той же самой.

На прошлой лекции мы обсуждали, что иногда необходимо иметь возможность выхода из середины цикла, и, как следствие, в современных ЯП, появились либо специальные циклы, так называемые циклы с управлением пользователем, либо специальные операторы, а именно операторы выхода из цикла. Семантика оператора выхода из середины переключателя естественным образом распространилась на все остальные циклы во всех современных ЯП (Си, Модула 2, С++, Java и C#), то есть в любом цикле любого из этих языков можно выполнить оператор break;, который означает выход из тела цикла, так же добавили оператор continue;, который означает тоже самое, но мы идём заново на новую итерацию цикла, игнорируя, все операторы, которые стоят после continue;. В ряде алгоритмов не употребление break;, continue; или переходов существенно ломает структуру алгоритма. Отличие ЯП не в принятии или непринятии возможности выхода из произвольной точки тела цикла, а в том, какие синтаксические конструкции они для этого используют.

В языках, основанных на Си, используют комбинации операторов break; и continue; с любым оператором тела цикла. Но возникает проблема вложенных циклов:

loop

loop

endloop

endloop

Довольно часто возникает проблема, когда нам нужен выход из середины вложенного цикла, но при этом выход вообще. Выход из общего цикла (например, найти в матрице первую строку сверху, содержащую нулевой элемент). В языках, основанных на Си, появилось ещё такое расширение: после break; можно ставить ещё имя метки, причём это имя метки помечает либо оператор переключателя, либо оператор цикла. Этот break L; может появляться внутри оператора, который помечен этой меткой и он означает, естественно, выход из цикла, который помечен этой меткой. Метки используются лишь для ограниченных операторов перехода. Тоже самое распространяется и на оператор continue L;.

В языке Ада общая форма цикла:

loop

S1;…;SN

endloop;

То есть, внешне это выглядит как бесконечный цикл. Но всё время считалось, что бесконечный цикл- это ошибка. Это так только для языков, где нет параллельного программирования (когда мы программируем параллельно или квазипараллельно, то очень часто процедуры, которые работают по процессу, и имеют вид бесконечного цикла, они закончатся, когда их убьёт кто-то сверху), кроме этого, с помощью этой конструкции реализуется цикл с управлением пользователем, если добавить ещё одну конструкцию: exit [метка][when B];. Меткой помечают тот цикл, из которого нужно выходить: <<метка>>. А условие B, вообще говоря, излишне, так как exit when B; равносильно if B then exit; endif;. Тут опять же принцип языкового дизайна: «если какая-то конструкция иногда бывает полезна, то её нужно включить». На эту общую форму цикла в языке Ада ложатся все остальные циклы.

Цикл «до»:

while B do

loop

S1;…SN

endloop

Цикл «пока»:

while B

Цикл с фиксированным числом повторений:

for i in дискретный диапазон

loop

Если нам надо в обратном направлении, то мы соответственно применяем конструкцию … in reduce … .

В Модуле 2 мы либо программируем с помощью классических циклов («до», «пока» и со счётчиком), либо используем цикл LOOP, и внутри этого цикла допускается оператор EXIT:

LOOP

EXIT;

END

Ещё два замечания по поводу циклов. Первое – цикл со счётчиком. Язык С++ был расширен относительно Си, с точки зрения цикла со счётчиком, а именно таким образом, что в некоторых случаях внутри выражения e1 допускалось объявлять переменные. Например, цикл прохождения по массиву мог быть реализован таким образом:

for (int i = 1; i < N; i++)

A[i];

Что похоже на Паскалевский (Модула 2 или Оберон) цикл:

For i := 0 to N-1 do

A[i];

Но где локализована эта переменная i? Страуструп принял мнение, что даже если есть такое описание, то переменная i считается описанной во внешнем блоке, то есть к ней можно получить доступ после выхода из цикла. Это было одно из неудачных решений. Во всех последователях языка С++ областью видимости переменной является тело цикла. В Аде также, но тип переменной указывать не нужно, он выводится неявно из дискретного диапазона. Опять же вспомним, что если компилятор не может вывести тип, то мы всегда можем подсказать ему с помощью так называемого указания типа: T’e, это не приведение типа, а всего лишь подсказка компилятору, как трактовать это выражение. И последнее - конструкция foreach (для каждого).

В Перл или Visual Basic есть эта специальная конструкция, которая внешне напоминает конструкцию Ады:

for i L..R loop

То есть у нас вводится переменная, которая локализована и которая последовательно пробегает значения из дискретного диапазона. В Перл существует конструкция – «ассоциативный массив»:

@names = {“str1”,”str2”,”str3”};

Он хранит в себе значения строк и это структура прямого поиска (строки – ключи):

$names{“str2”};

foreach($names) {

println($names)

}

$names в foreach означает, что переменная names пробегает последовательно все значения. Подобного рода парадигма сводится к тому, что у нас есть коллекция, то есть структура данных, которая хранит в себе другие структуры данных. И довольно часто, независимо от устройства коллекции нам необходимо пробежать всю коллекцию от первого до последнего элемента (часто даже порядок не важен). При этом если программировать в обычном стиле, то вид соответствующего цикла очень сильно зависит от вида соответствующей коллекции. Коллекции – один из важнейших типов данных. В С++ все типы данных, которые нам могут понадобится, моделируем при помощи классов. Вот, например, библиотека стандартных шаблонов STL, выбирает, похожий на foreach подход к программированию коллекций, а именно там любой контейнерный класс должен содержать внутри себя некоторый класс, который называется iterator. По соглашению все контейнерные классы обладают классом iterator, а класс iterator должен содержать перекрытые операции: конструктор и инициализация, (итератор просто держит очередной элемент коллекции) перекрытую операцию ++ продвижение на следующий элемент в этой коллекции и -> оператор разыменования. Он ведёт себя как указатель в каком-то массиве. Похоже на стандартный подход, только обобщённый на произвольную структуру данных. Если у нас есть коллекция call c; мы объявляем итератор: call::iterator e. Инициализируем соответствующий итератор p и по соглашению у нас всегда есть функции begin(); - инициализация соответствующего итератора началом коллекции и end(); и, по STL’ному соглашению соответствующий цикл пробега по коллекции принимает вид:

for (p = c.begin(); p != c.end(); p++)

p->

В C# оператор foreach:

foreach(p in C)

Но доступ теперь не через указатель, а через «p.», которое ссылается на очередной элемент коллекции С. Этот оператор отражает концепцию современных ЯП, которая называется рефлексией. С её помощью мы управляем поведением компилятора и среды времени выполнения. Здесь рефлексия заключается в том, что эта операция перечисления in применима не к встроенным в язык типам данных, а именно к пользовательским классам, которые должны реализовывать так называемый «переходный интерфейс». Далее вернёмся к этому вопросу. С помощью рефлексии привязываем соответствующие объекты к операторам ЯП.

В Java это понятие работает на уровне стандартной библиотеки (а не встроено в язык). Есть некий стандартный интерфейс и если классы поддерживают его, то с ними будут работать все программы стандартной библиотеки, без её перекомпиляции. Этот подход ближе к STL. Но, если STL построена на понятие template (шаблон), то в Jave нет никакой статической параметризации нет и всё это построено на концепции динамического интерфейса. В C# пошли ещё дальше и встроили некие конструкции (foreach, …), которые позволяют некие языковые конструкции прямо связать с пользователем.

3)Переходы. Необходимость в операторе перехода постоянно падает. Общий вид оператора перехода, если он присутствует (из рассмотренных языков отсутствует в Модула 2, Оберон и Java) имеет вид goto метка;, причём на него накладывается куча ограничений. А именно все конструкции современных ЯП таковы, что для них существует только один вход, иначе говоря, мы никогда не сможем войти внутрь составного оператора, цикла или условного ветвления. Следовательно, переход может быть только наружу, далее этот переход, как правило, ограничен некой статической областью видимости, например, в языках, основанных на Си, и во многих других языках, переход ограничен только блоком тела процедуры (то есть goto – локальный переход). В Паскале, который поддерживает вложенные процедуры, переход допустим только в рамках одной процедуры. В некоторых ЯП (например, Си) есть так называемый нелокальный переход setjmp, но мы не будет рассматривать эту концепцию, как предельно устаревшую. Структурное программирование существенно сократило область использования оператора перехода (все эти формы оператора перехода не противоречат концепции один вход, один выход):

  • выход из середины цикла (break;, exit)

  • выход из функции (return [e];)

  • обработка ошибочных, аварийных ситуаций (ошибки бывают в системе или во входных дынных, а мы хотим надёжную систему, которая адекватно реагирует на ошибку)

Во многих случаях в процедуре, где была обнаружена ошибка, исправить ошибку невозможно. Что делать: спросить программу, предупредить пользователя, то ли сделать что-то ещё, но сама процедура никакого решения не принимает. Поэтому она должна просигнализировать об ошибке. В старых ЯП (Си, Паскаль) единственная возможность сигнализации об ошибке – возврат из процедуры с какой-то сигнализацией об ошибке. Часто у процедуры возвращаемое значение типа int f(…), которое сигнализирует только об одном – нормально закончилась процедура или не нормально. Все системные вызовы библиотек языка Си (подавляющее большинство) описаны именно таким образом, так они всегда должны завершаться корректно. Значение >= 0 говорит о том, что всё нормально, а значение < 0 (обычно –1) говорит о том, что что-то не то. И надо возвращаться из процедуры. Но очень часто не хватает одного оператора return; так как необходимо обеспечить чистку ресурсов (закрыть файлы, …):

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5302
Авторов
на СтудИзбе
416
Средний доход
с одного платного файла
Обучение Подробнее