. . . . . . . . . . . . . .
<имяk>: <типk>;
end
где <имяi> — имя i-го поля, <типi> — тип i-го поля.
Типы данных: Объединения и вариантные записи.Обычные записи представляют объекты данных с общими атрибутами (одинаковым
перечнем полей). Вариантные записи представляют объекты, в которых лишь часть
атрибутов (полей) является общей.
Объединение — это специальный случай вариантной записи с пустой общей
частью.
Вариантные записи имеют часть, общую для всех записей этого типа, и вариант-
ную часть, специфичную для некоторого подмножества записей.
Типы данных: Множества.Множество — это структура, содержащая неупорядоченный набор различных зна-
чений. В Паскале значения множеств задаются записью элементов в квадратных
скобках:
['0' .. '9'] ['a'.. 'z', 'A'.. 'Z'] [ ]
Все элементы множества должны быть одного и того же простого типа — целые
числа, перечисления или поддиапазоны в этих типах.
Объявление множественного типа
type <ТипМножества> = set of <БазовыйТип>;
определяет все подмножества, составленные из комбинаций значений базового
типа. Если базовый тип имеет n значений, то тип множества позволяет генериро-
вать 2n значений.
Для переменной А
var A : set of [1 .. 3];
разрешены подмножества:
[ ], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]
Ссылочные типы и операции над ссылками.Ссылки очень часто используются для передачи параметров в подпрограммы. Ссылочные параметры неявно разыменовываются, а их семантика полностью соответствует сути передачи по ссылке. Переменная ссылочного типа похожа на указатель, но имеет одну важную особенность. Указатель ссылается на адрес в памяти, а ссылка ссылается на объект или значение в памяти. Переменная ссылочного типа в языке C++ — это константный указатель, который всегда неявно разыменован. В определении имя переменной ссылочного типа предваряется символом амперсанда (&). Например,
int sum = 0;
int &ref_sum = sum;
. . .
ref_sum = 150;
В этом фрагменте переменные sum и ref_sum считаются алиасами.
Одним полезным применением ссылок являются списки параметров функции, при помощи которых они могут передавать параметры, используемые для вывода без явного взятия адреса вызывающим. Например:
void square(int x, int& result) {
result = x * x;
}
Динамические структуры данных.Растущие и сжимаемые (в ходе выполнения программы) структуры реализуют-
ся на основе записей и указателей. Их создание возможно благодаря соблюдению
принципа статического формата — размер и формат памяти для каждого типа из-
вестны статически, перед выполнением программы.
Так как формат определяется в период компиляции, динамические структуры
(растущие и сжимаемые в период выполнения) реализуются с помощью элемента
фиксированного размера.
Связная структура данных растет, когда элемент размещается и связывается
с другими элементами, структура данных сжимается, когда элемент удаляется.
Элементы и связи используются также для реализации таких структур данных,
как связные списки и деревья.
Повисшие ссылки и утечки памяти.Повисший указатель — это указатель на память, которая используется для
других целей. Типичный случай — память уже перераспределена. К повисшему
указателю приводит оператор dispose(p). Повисшие указатели понижают без-
опасность программ.
Память, которая распределена, но недоступна, называется мусором (garbage).
Говорят, что программы, которые создают мусор, дают утечки памяти (memory
leaks). К утечкам памяти могут привести присваивания между указателями. Утечка
памяти может понизить производительность, но не безопасность.
Особенности указателей в Паскале. Особенности указателей в Си.Язык Паскаль проектировался в расчете на максимальную безопасность работы
с этой особой категорией — динамическими объектами. Любой динамический объект создается в период выполнения программы, собственного имени не имеет, доступен только косвенно, через указатель. Ну а указатель —источник повышенной опасности, так как результат разыменования повисшего указателя непредсказуем.
У операций с указателями два недостатка:
1. Утечки памяти (это неприятность).
2. Повисшие указатели. Способ устранения — присваивать указателю значение nil. Реализовать это можно как отдельный оператор или как завершающую фазу выполнения
оператора dispose.
В отличие от языка Pascal аппарат указателей в С ориентирован не на обеспечение
максимальной безопасности, а на предоставление программисту максимальной
гибкости.
1. В С указатели используют для доступа ко всей памяти, то есть для доступа как
к обычным переменным (статическим, с именами), так и к безымянным переменным.
2. Выделение и освобождение динамической памяти не определяется средствами
языка С (в отличие от языка Pascal), здесь используются библиотечные функ-
ции malloc, free.
3. В С отсутствуют ограничения на вид и тип переменных, на которые могут
указывать указатели. Допускается проведение арифметических операций над
указателями (адресами). В результате возможны многочисленные утечки памяти,
появление повисших указателей.
Ссылки как посредники.Очень часто указатели (ссылки) используют для косвенного обращения к большим структурам данных, повышая скорость и сокращая затраты на организацию доступа.
Ссылки дают возможность:
- Организация перекрестной адресации Повышение надежности доступа к важной информации Перемещение данных из одной области в другую область памяти
Объявления же указателей в языке С имеют вид:
int ∗pa;
float ∗pb;
Форма такого объявления задумывалась как мнемоническая — специально для
облегчения его понимания и использования. Первое объявление означает, что вы-
ражение ∗pa имеет тип int. Иными словами, результат разыменования указателя pa
имеет тип int.
После обработки этих объявлений указатель pa может хранить адреса целых
переменных, а указатель pb — адреса вещественных переменных.
Использование массивов и указателей в С тесно связано. Фактически имя
массива А является указателем на его начальный, нулевой элемент A[0]. Таким об-
разом, использование указателей для доступа к обычным массивам, размещенным
в статической памяти, здесь считается обычным приемом.
Характеристики переменной. Тип выражения.Переменная является объектом данных, который программист явно определяет
и называет. Имя переменной считают нечувствительным к регистру, если не имеет
значения, какими буквами оно записано (заглавными или строчными). Впрочем,
во многих языках имена переменная и ПЕРЕМЕННАЯ обозначают разные объекты
данных. В течение жизни значение переменной может многократно изменяться.
Говорят, что при этом происходит новое связывание переменной с ее значением.
Как и каждая переменная, каждое выражение тоже должно иметь тип. Он должен
быть известен и зафиксирован в период выполнения. Этот тип зависит от типа
переменных в выражении, а также от операций выражения. Например, выражение
2 + 3 имеет целый тип, так как и 2 и 3 являются целыми числами, а сумма целых —
тоже целое число.
Тип выражения логически выводится в период компиляции.
Набор правил для определения типа выражения входит в систему типизации
языка. Система типизации отвергает выражение, если оно не сопоставимо с типом.
Правила системы типизации определяют корректность использования каждой
операции языка в выражении.
Эквивалентность типов.Вопрос об эквивалентности типа возникает при проверке выражений и операто-
ров. Например, при вызове операции сравнивается тип данных переданного аргу-
мента с предусмотренным для этой операции типом. Если эти типы одинаковы, то
аргумент принимается и операция выполняется. Если эти типы различны, то либо
создавшаяся ситуация расценивается как ошибка, либо применяется приведение
типа аргумента к предусмотренному типу.
Правила эквивалентности типов просты и точны для предопределенных ска-
лярных типов. Однако в случае составных типов, таких как массивы, записи и не-
которые типы, определенные пользователем, правила существенно усложняются.
Возможны два вида эквивалентности:
. структурная эквивалентность;
. именная эквивалентность.
При структурной эквивалентности два типа считаются одинаковыми, если име-
ют одинаковую внутреннюю структуру, то есть состоят из одинакового соединения
одинаковых компонентов. Структурная эквивалентность типов означает, что
две переменные имеют эквивалентные типы, если их типы обладают идентичной
структурой.
При именной эквивалентности каждое новое определение типа вводит новый
тип (с новым именем). Если программист записал определения двух типов, то эти
типы различны. В общем случае, именная эквивалентность типов означает, что две
переменные имеют эквивалентные типы в любом из двух случаев:
. они определены в одном и том же объявлении;
. в их объявлениях используется одно и то же имя типа.
Преобразование типа и явное приведениеСуществует много случаев, в которых ожидаются величины определенных типов.
В операторе
а := выражение;
мы ожидаем в правой части тот же тип, который имеет а. В выражении a + b пере-
гружаемый символ + означает или целое сложение, или вещественное сложение,
поэтому мы ожидаем, что числа a и b являются либо целыми, либо вещественными.
При вызове процедуры выч (арг1, арг2, арг3) мы ожидаем, что типы аргумен-
тов будут совпадать с типами формальных параметров, объявленных в заголовке
процедуры.
Предположим, что в каждом из этих случаев ожидаемые и обеспечиваемые типы
должны быть одинаковы. Тогда, если программист захочет использовать значение
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 |


