Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры [4747 вопросов].doc
Скачиваний:
83
Добавлен:
15.06.2014
Размер:
407.04 Кб
Скачать

32 Выражения и операторы присваивания. Способы реализации.

Большинство свойств арифметических выражений в языках программирова­ния произошли от условностей, принятых в математике. В языках программирования арифметические выражения состоят из операторов, операндов, круглых скобок и вызо­вов функций. Оператор может быть унарным (unary), что означает наличие у него одно­го операнда, бинарным (binary), имеющим два операнда, и тернарным (ternary), у кото­рого есть три операнда.

В большинстве императивных языков программирования бинарные операторы являют­ся инфиксными, т.е. они появляются между операндами. Одним из исключений является язык Perl, в котором есть префиксные операторы, т.е. предшествующие своим операндам.

Цель арифметических выражений - указать арифметическое вычисление. Реализа­ция такого вычисления должна выполнять два действия: выбирать операнды (обычно из памяти) и выполнять над ними арифметические действия.

Ассоциативность

Порядок вычисления операндов

Преобразование типов :сужающие,расширяющие

Явное преобразование типов

Выражения отношения

Оператор отношений (relational operator) сравнивает значения двух своих операн­дов. Выражение отношений (relational expression) состоит из двух операндов и одного оператора отношений. Значение выражения отношений принадлежит к булевскому типу, за исключением случая, когда в языке нет булевского типа. Операторы отношений обыч­но перегружаются для большого числа типов. Операция, определяющая истинность или ложность выражения отношений, зависит от типов операндов. Она может быть простой (для целых операндов) или сложной (для операндов, являющихся символьными строка­ми). Обычными типами операндов, которые могут использоваться в выражениях отно­шений, являются числовые типы, строки и порядковые типы.

Булевские выражения

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

Простые присваивания

Множественные целевые объекты

Условные целевые объекты

Составной оператор присваивания позволяет сокращенно задавать часто используе­мую форму присваивания. С помощью этого метода можно сократить запись присваива­ния, при котором целевая переменная используется в качестве первого операнда в пра­вой части выражения, например: а = а + b. Синтаксис составного оператора присваивания языка С представляет собой объединение нужного бинарного оператора и оператора =. Например, выражение

Унарные операторы присваивания

Постфиксный оператор sum = count ++; вначале присваивает значение переменной count переменной sum, после чего перемен­ная count увеличит свое значение на 1. То же действие можно задать следующими опе­раторами: sum = count; count = count + 1;

33.Структуры управления на уровне операторов. Способы реализации.

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

Существует один вопрос, связанный с разработкой управляющих структур: может ли управ­ляющая структура иметь несколько входов. Наличие нескольких входов возможно только в языках, ко­торые содержат операторы goto и метки операторов.

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

Оператор ветвления (selection statement) предоставляет программисту средства вы­бора между несколькими путями выполнения программы. Такие операторы являются основными и существенными частями всех языков программирования.

Операторы ветвления разделяются на две основные категории: двухвариантные и n - вариантные, или многовариантные операторы ветвления. В категории двухвариантных операторов ветвления существует вырожденный вид оператора, называемый одновариантным оператором ветвления. Существует также вырожденный многовариантный опе­ратор ветвления, арифметический оператор IF в языке FORTRAN, являющийся трехвариантным оператором ветвления.

Двухвариантные операторы ветвления

Несмотря на то что двухвариантные операторы ветвления в современных императив­ных языках совершенно одинаковы, вариации в их оценках основываются на совокупно­сти соображений, связанных с разработкой языка.

Вложенные операторы ветвления

Интересная проблема возникает, если допускается вложение двухвариантных конст­рукций ветвления. Рассмотрим следующий фрагмент кода, напоминающего программу на языке Pascal:

Специальные слова и замыкание оператора ветвления

Операторы цикла (iterative statements) — это операторы, вынуждающие оператор или набор операторов выполняться один и сколько угодно раз, или не выполняться ни разу. Каждый язык программирования содержал некоторый метод для повторения выполнения сегмента кода.

Логически управляемые циклы

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

Некоторые императивные языки (например, Pascal, С, C++ и Java) имеют логически управляемые циклы как с предварительной, так и последующей проверкой условий, ко­торые не являются особым видом циклов со счетчиком. В языке C++ циклы с предвари­тельной и последующей проверкой условий имеют следующий вид: while (выражение) тело цикла

34. 35 Подпрограммы. Способы реализации.

Общие свойства подпрограмм

Каждая подпрограмма имеет один вход.

На время выполнения вызываемой подпрограммы выполнение вызывающего ее модуля откладывается. В каждый момент времени вы­полняется только одна подпрограмма.

Управление после выполнения подпрограммы всегда возвращается в вызывающий модуль.

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

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

Функции по своей структуре напоминают процедуры, но они семантически модели­руют математические функции. Если функция является точной моделью, то она не имеет побочных эффектов. Это значит, что она не изменяет ни свои параметры, ни какие-либо другие переменные, определенные вне функции.

Методы передачи параметров :

по значению

Когда параметр передается по значению (passed by value), значение фактического параметра используется для инициализации соответствующего формального параметра, который в дальнейшем действует как локальная переменная в подпрограмме, реализуя таким образом семантику режима ввода.

по результату

Передача по результату (pass-by-value) представляет собой модель реализации ре­жима вывода. Когда параметр передается по результату, никакое значение в подпро­грамму не передается. Соответствующий параметр действует как локальная переменная, но непосредственно перед возвращением управления обратно в вызываю­щий модуль его значение передается фактическому параметру, который должен пред­ставлять собой переменную. Если возвращается значение (а не путь доступа к нему), как это обычно происходит, передача по результату также требует дополнительной памяти и операций копирования, необхо­димых для передачи по значению. Как и при передаче по значению, трудности реализа­ции передачи по результату с помощью передачи пути доступа к данным обычно приво­дят к тому, что она реализуется на основе физического перемещения данных. В этом случае необходимо гарантировать, что первоначальное значение фактического парамет­ра не используется в вызывающем модуле.

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

Передача по значению и результату (pass-by-value-result) представляет собой мо­дель реализации режима ввода-вывода, в котором фактические значения физически пе­ремещаются. Эта модель представляет собой комбинацию передачи по значению и передачи по результату. Значение параметра используется для инициализации соответствующего параметра, который затем действует как локальная переменная.

по ссылке :

Передача по ссылке (pass-by-reference) — это вторая модель реализации режима вво­да-вывода. Вместо того, чтобы передавать данные туда и обратно, как при передаче по зна­чению и результату, метод передачи по ссылке передает путь доступа к данным (обычно — просто адрес) в вызываемую подпрограмму. Преимущество передачи по ссылке состоит в том, что процесс передачи эффективен сам по себе с точки зрения как времени, так и пространства. Не требуется ни тиражиро­вать память, ни копировать что-либо.

по имени

Передача по имени (pass-by-name) — это метод передачи параметров в режиме вво­да-вывода, не соответствующий какой-то отдельной модели реализации. Когда параметры передаются по имени, фактический параметр в действительности буквально заменяется соответствующим формальным параметром во всех местах под­программы, где он появляется. При передаче по имени формальный параметр также связывается с методом доступа во время вызова про­граммы, однако фактическое связывание с некоторым значением или адресом отклады­вается, пока формальному параметру не будет присвоено какое-нибудь значение, либо на него не будет сделана ссылка. Целью такого позднего связывания в методе передаче параметров по имени является гибкость.

Параметризованные подпрограммы.

Перегруженные подпрограммы.

Доступ к локальным переменным.

Перегруженный оператор имеет несколько значений. Значение конкретного экземп­ляра перегруженного оператора определяется типами его операндов. Если оператор * имеет два операнда с плавающей точкой в программе на языке С, он означает умножение чисел с плавающей точкой. Однако, если тот же оператор имеет два целочис­ленных операнда, он означает целочисленное умножение.

Перегруженная подпрограмма (overloaded subprogram) — это подпрограмма, имя которой совпадает с именем другой подпрограммы в той же среде ссылок. Каждая вер­сия перегруженной подпрограммы должна иметь свой уникальный протокол, т.е. она должна отличаться от других версий количеством, порядком, типами своих параметров или типом возвращаемого значения, если она является функцией. Значение вызова пере­груженной подпрограммы определяется списком фактических параметров (и/или, воз­можно, типом возвращаемого значения при использовании функции).

Описание переменной вне подпрограммы.

Блоки глобальных данных.

Реализация подпрограмм

Общая семантика вызовов и возвратов

Вызов подпрограммы и операции возврата управления, взятые вместе, называются связыванием подпрограмм (subprogram linkage). Любой метод реализации подпро­грамм должен основываться на семантике связывания подпрограмм.

Вызов подпрограммы содержит механизм передачи параметров. Если локальные пе­ременные не являются статическими, вызов приводит к выделению памяти для локаль­ных переменных, объявленных в вызываемой подпрограмме, и связывает их с этими ячейками памяти. Он должен сохранять текущее состояние выполняемого модуля, вы­звавшего подпрограмму; передавать управление коду подпрограммы и гарантировать, что оно будет возвращено в нужное место после выполнения подпрограммы. В заключе­ние вызов должен обеспечить доступ к нелокальным переменным, видимым в вызывае­мой подпрограмме.

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

Реализация подпрограмм

Семантика вызова подпрограмм требует выполнения следую­щих действий.

Сохранить текущее состояние выполняемого программного модуля.

Передать параметры.

Передать адрес возврата вызываемой подпрограмме.

Передать управление вызываемой подпрограмме.

При возврате из подпрограмм в языке выполняются следующие действия.

Если использовался метод передачи параметров по значению и результату, теку­щие значения этих параметров присваиваются соответствующим фактическим па­раметрам.

Если подпрограмма представляет собой функцию, то значение функции переме­щается в место, доступное вызывающему модулю.

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

Управление передается назад вызывающему модулю.

Действия, связанные с вызовом и возвратом, требуют выделения памяти для следую­щих данных.

Информация о состоянии вызывающего модуля.

Параметры.

Адрес возврата.

Возвращаемое значение функции.

Подпрограмма состоит из двух отдельных частей: кода подпрограммы (являющегося неизменным), локальных переменных и дан­ных (которые могут изменяться при выполнении подпрограммы). Формат, или структура, части подпрограммы, не являющейся кодом, называется за­писью активации (activation record), или активационной записью, поскольку данные, которые она описывает, относятся только к активации подпрограммы. Форма записи активации является статичной. Экземпляр записи активации (activation record instance) — это конкретный образец записи ак­тивации, или набор данных в форме активационной записи.

Рекурсивный вызов