Рубрики: КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

про компютерное железо, документация, языки программирования

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

Фигурные скобки

(**) (Открывающие и закрывающие фигурныескобки) обозна-
чают начало и конец составного оператора:

if (d == z)
(*
++x
func();
*)

Закрывающая фигурная скобка служит терминатором состав-
ного оператора, поэтому (;) (точка с запятой) после *) не
требуется, за исключением структур или объявлений классов.
Часто точка с запятой недопустима, как например в случае

if (оператор)
(**); /* недопустимое использование точки с запятой */
else

Запятая

Запятая (,) отделяет элементы списка аргументов функции:

void func(int n, float f, char ch);

Запятая часто используется как операция в «операции с

— 26 —
запятой». Обе эти операции являются допустимыми, но для раз-
личения их вы должны использовать круглые скобки:

func(i, j); /* вызов функции с двумя аргументами */
func((exp1, exp2), (exp3, exp4, exp5)); /* также вызов
функции с двумя аргументами */

Точка с запятой

Точка с запятой (;) служит терминатором оператора. Лю-
бое допустимое выражениеС (включая и пустое выражение), за
которым следует (;), интерпретируется как оператор, называе-
мый оператором выражения. Выражениевычисляется, а его значе-
ние отбрасывается. Если такое выражение не имеетпобочных эф-
фектов, то TurboC++ может его проигнорировать.

a + b; /* a + b вычисляется, но полученное значение
теряется */
++a; /* имеется побочный эффект для a, но результат ++a
*/
/* теряется */
; /* пустое выражение = нулевой оператор */

Точки сзапятой частоиспользуются для создания пустых
операторов:

for (i = 0; i < t; i++) (* ; *) Двоеточие Двоеточие (:) служит для обозначения оператора с меткой: stsrt: x=0; ... goto stsrt; ... switch (a)(* case 1: puts("Первый"); break; case 2: puts("Второй"); break; ... default: puts("Ни тот, ни другой!"); break; *) Метки рассматриваются на стр.92 оригинала. Многоточие Многоточие (...) представляет собой три последовательно расположенные точки без пробелов между ними. Многоточия ис- пользуются в списках формальных аргументовпрототипов функций для обозначения переменногочисла аргументов, либо аргументов с изменяющимся типом: void func(int n, char ch,...); Данное объявление указывает, что func будет определена таким образом, что вызовы ее должны содержать как минимум два аргумента, int и char,но также могут иметь и любое число дополнительных аргументов. В С++ запятую, предшествующую многоточию, можно опустить. - 27 - Звездочка (объявление указателя) Звездочка (*) в объявлении переменной обозначает созда- ние указателя на тип: char *char_ptr; /* объявление указателя на тип char */ Можно объявить указатели с несколькими уровнями косвен- ности, что обозначается соответствующим количеством звездо- чек: int **int_ptr; /* указатель на указатель на int */ double ***double_ptr /* указатель на указатель на указатель на тип double */ Звездочка также используется в качестве операции обра- щения через указатель, либо операции умножения: i = *int_ptr; a = b * 3.14; Знак равенства (инициализатор) Знак равенства (=) разделяет объявления переменных от списков инициализации: char array[5] = (* 1, 2, 3, 4, 5 *); int x = 5; В функциях С никакой код не может предшествовать ника- ким объявлениям переменных. В С++ объявления любого типа мо- гут находиться (с некоторыми ограничениями) в любой точке внутри кода. В списке аргументов функции С++ знак равенства указыва- ет на значение параметра по умолчанию: int f(int i = 0) (* ... *) /* параметр i имеет значение по умолчанию ноль */ Знак равенства используется также как операция присвое- ния в выражениях: a = b + c; ptr = farmalloc(sizeof(float)*100); Знак фунта (директива препроцессора) Знак фунта (#) означает директиву препроцессора, если она является первым не-пробельным символом встроке. Он зада- ет действие компилятора, не обязательно связанное с генера- цией кода. Более подробно директивы препроцессора описаны на стр.133 оригинала. # и ## (двойной знак фунта) также используются как опе- рации замены и слияния лексем на фазе сканирования кода препроцессором. Объявления В данном разделе кратко рассматриваются концепции, свя- занные с объявлениями: объектов, типов, классов памяти, кон- текста, видимости, продолжительности и типом компонов- ки.Преждечем перейти к рассмотрению полного синтаксиса объявления, важно иметь общее представление об этих поняти- ях. - 28 - Контекст, видимость, продолжительность и тип компоновки определяют части программы,из которых могут быть сделаны до- пустимые ссылки на идентификатор сцельюдоступа к соответс- твующему объекту. Контекст обсуждаетсяна стр.29 оригинала, видимость - на стр.30; продолжительность рассматривается, начиная со стр. 31, а тип компоновки - на стр.32. Объекты Объектом называется идентифицируемая область памяти, которая может содержать фиксированное значение переменной (или набор таких значений). (Используемое в данном случае слово "объект" не следует путать с более общим термином, ис- пользуемым в объектно-ориентированных языках - см. главу 5, "Введение в С++" в документе "Начало работы".) Каждая вели- чина имеет связанное с ней имя и тип (который также называют типом данных). Имя используется для доступа к объекту. Имя может являться простым идентификатором, либо сложнымвыраже- нием, уникальным образом "указывающим" на данный объект. Тип используется для - для определения требуемого количества памяти при ее исходном распределении, - для интерпретации битовых коды, находимых в объектах при последующих к ним обращениях, - а также в многочисленных ситуациях контроля типа, требуемого для обнаружения возможных случаев недопустимого присваивания. Turbo C++ поддерживает многие стандартные (предопреде-

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

циализатор
new имя-типа

— 72 —

местоположение: (только С++)
(список-выражений)

имя-ограниченного-типа: (только С++)
спецификатор-типа

декларатор-ограничения: (только С++)
операция-указателя
декларатор-ограничения []

выражение-отмены-распределения: (только С++)
delete выражение-приведения
delete [выражение] выражение-приведения

выражение-приведения:
унарное-выражение
(имя-типа) выражение-приведения

выражение-типа-ссылки:
выражение-приведения
выражение-типа-ссылки .* выражение-приведения (только С
++) выражение-типа-ссылки -> выражение-приведения (только С+
+)

выражение-типа-умножения:
выражение-типа-ссылки
выражение-типа-умножения * выражение-типа-ссылки
выражение-типа-умножения / выражение-типа-ссылки
выражение-типа-умножения % выражение-типа-ссылки

выражение-типа-сложения:
выражение-типа-умножения
выражение-типа-сложения + выражение-типа-умножения
выражение-типа-сложения — выражение-типа-умножения

выражение-типа-сдвига:
выражение-типа-сложения
выражение-типа-сдвига > выражение-типа-сложения

выражение-отношения:
выражение-типа-сдвига
выражение-отношения < выражение-типа-сдвига выражение-отношения > выражение-типа-сдвига
выражение-отношения = выражение-типа-сдвига

выражение-типа-равенства:
выражение-отношения
выражение-типа-равенства = выражение-отношения
выражение-типа-равенства != выражение-отношения

выражение-И:
выражение-типа-равенства
выражение-И & выражение-типа-равенства

выражение-исключающее-ИЛИ:
выражение-И
выражение-исключающее-ИЛИ выражение-логическое-И

выражение-включающее-ИЛИ:
выражение-исключающее-ИЛИ
выражение-включающее-ИЛИ \! выражение-исключающее-ИЛИ

выражение-логическое-И:
выражение-включающее-ИЛИ

— 73 —
выражение-логическое-И && выражение-включающее-ИЛИ

выражение-логическое-ИЛИ:
выражение-логическое-И
выражение-логическое-ИЛИ !! выражение-логическое-И

условное-выражение:
выражение-логическое-ИЛИ
выражение-логическое-ИЛИ ? выражение : условное-выражение

выражение-присвоения:
условное-выражение
унарное-выражение операция-присвоения выражение-присвоения

операция-присвоения: одно из
= *= /=%= += -=

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

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

Стандартные библиотеки Turbo C++, а также ваши собс-
твенные программы и файлы заголовковобеспечиваютоднозначные
идентификаторы (или выводимые из них выражения) и типы, та-
ким образом, что Turbo C++ можетнепротиворечиво выполнять
доступ, интерпретировать и (возможно) изменять битовые коды
в памяти, соответствующей каждому активному объекту вашей
программы.

Объявления устанавливают необходимыесоотношения распре-
деленияпамятимежду идентификаторами и объектами. Каждое объ-
явление связываетидентификатор с некоторым типом данных.
Большинство объявлений, известных как объявления определе-
ния, также задает создание (т.е. где и когда) объекта; иначе
говоря, распределениефизической памяти и ее возможную иници-
ализацию. Прочие объявления, называемые объявлениями ссылки,
просто делают указанные в них идентификаторы известными ком-
пилятору. Один и тот же идентификатор может иметь множество
объявлений ссылки, особенно в многофайловых программах, од-
нако для каждого идентификатора допустимо только одно объяв-
ление определения.

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

— 29 —
Именующие выражения (Lvalues)

Именующее выражение представляет собой локатор объекта,
выражение, которое обозначает объект. Примером именующего
выражения может служить *P, где P это выражение, дающее не-
пустой указатель. Модифицируемое именующее выражение -это
идентифицирующее выражение, относящееся к объекту, к которо-
му возможен доступ и допустимо его изменение в памяти. Ука-
затель константы const, например, не является модифицируемым
именующим выражением. Указатель на константуможетбыть изме-
нен (а подлежащее обращению по этому указателю значение — не
может).

Исторически в слове Lvalues буква L означает «левый»;
это означает, что Lvalue допускается в левой части (априни-
мающей части) оператора присваивания. Здесь в левой части
оператора присваивания допустимы только модифицируемые име-
нующие выражения. Например, если a и b — это не являющиеся
константами целочисленные идентификаторы с правильно распре-
деленнымидля них областями памяти, тооба они являются моди-
фицируемыми именующими выражениями, и присваиваниятипа a =
1;и b = a + b; вполне допустимы.

Значения переменной (Rvalues)

Выражение a + b не можетявляться именующим выражением,
и выражение типа a + b = a недопустимо, поскольку выражение
в левой части не относится кобъекту. Такие выражения часто
называют значением переменной (значение правой части выраже-
ния).

Типы и классы памяти

Для связи идентификаторов с объектами требуется, чтобы
каждый идентификаторимел как минимум два атрибута: класс па-
мяти и тип (иногда его называют типомданных). Компиля-
торTurboC++ определяет эти атрибуты появным или неявным объ-
явлениям в исходном коде программы.

Класс памяти задает размещение объекта (сегмент данных,
регистр, куча или стек) и продолжительность его времени су-
ществования (все время работы программы, либо же при выпол-
нении некоторых конкретных блоков кода). Класспамятиможет
быть установлен синтаксисом объявления, расположением в ис-
ходном коде или обоими этими факторами.

Тип, как говорилосьвыше,определяет размер памяти, расп-
ределяемый объекту, и то, каким образом программа будет ин-
терпретировать битовыекоды, находящиесяв памяти,
распределенной объекту. Типданныхможнорассматриватькак мно-
жество значений (часто зависимо от реализации), которые мо-
жет принимать идентификатор данного типа, совокупно с мно-
жеством операций, выполнениекоторых допустимо для значений
этого типа. Специальная операциявремени компиляции,sizeof,
позволяет определить размер в байтах любого стандартного или
определяемого пользователемтипа данных; дополнительную ин-
формацию об этой операции см. на стр. 81 оригинала.

Контекст

Контекстом идентификатора называется часть программы, в
которой данный идентификатор может быть использован для дос-
тупа к связанному сним объекту. Существует пять категорий
контекста: блок (или локальный), функция, прототип функции,
файл и класс (только для С++). Контекст зависит от того, как
и где объявлены идентификаторы.

— 30 —
Контекст блока

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

Контекст функции

Единственными идентификаторами, имеющими контекст типа
функции, являются метки операторов. Именаметок могут быть
использованыв операторах goto влюбой точке функции,где объ-
явлена данная метка. Метки объявляютсянеявно; для этого за-
писывается имя_метки: и за ним оператор. Имена меток в пре-
делах функции должны быть уникальными.

Контекст прототипа функции

Идентификаторы, объявленные в списке объявлений
параметров в прототипе функции (не являющиеся частью опреде-
ления функции) имеют контекст прототипа функции.Конец этого
контекста совпадает с концом прототипа функции.

Контекст файла

Идентификаторы с контекстомфайла, называемые часто гло-
бальными, объявляются вне всех блоков и классов; их контекст
лежит между точкой объявления и концом исходного файла.

Контекст класса (С++)

Классом можно считать именованный набор компонентов,
включая сюда структуры данных и действующие с ними функции.
Контекст класса относится, за некоторыми исключениями, к
именам компонентов конкретного класса. Классы и ихобъекты
имеют множество специальных правил доступа и определения
контекста; см. стр. 102 — 113 оригинала.

Контекст и пространства имен

Пространство имен — это контекст, в пределах которого
идентификатордолженбыть уникальным. В С существует четыре
раздельных класса идентификаторов:

1. Имена меток операторов goto. Эти имена должны быть
уникальными в пределах функции, в которой они объявлены.

2. Теги структур, объединений и перечислимых данных.
Они должны быть уникальными в пределах блока, в котором они
определены. Теги, объявленные вне какой-либо функции, должны
быть уникальными относительно всех тегов, определенных вов-
не.

В С++ структуры, классы и перечислимые данные относятся
к одному и тому же пространству имен.

3. Имена компонентовструктур и объединений. Они должны
быть уникальными в пределах структуры или блока, в которомо-
ни определены. На тип или смещение с одним и тем же именем в
различных структурах ограничений не существует.

4. Переменные, определения типа и компоненты перечисли-
мых данных. Они должны бытьуникальными вконтексте, где они
определены. Идентификаторы, объявленные внешними, должны
быть уникальными среди переменных, объявленных вовне.

— 31 —

Видимость

Видимостью идентификатора называется область исходного
кода программы, из которого допустим нормальный доступ к
связанному с идентификатором объекту.

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

Видимость не может выходить за пределы контекста; но
контекст может превышать видимость.


(*
int i; char ch; // автоматическое распределение по
умолчанию
i = 3; // int i и char ch в контексте и видимы

(*
double i;

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

цируют, и используют значение одного и того же объекта.
Рассмотрим выражение

i = v[i++]; // i неопределено

Значение i зависит от того, выполняется ли инкременти-
рование до или после присвоения. Аналогичным образом,

int total = 0;

— 75 —
sum = [total = 3] + (++total);// sum = 4 или sum = 7 ??

имеет неоднозначность идентификаторов sum и total. Ре-
шение состоит в том, чтобы упростить выражение при помощи
временной переменной:

int temp, temp = 0;
temp = ++total;
sum = (total = 3) + temp;

Когда синтаксиспринудительно устанавливает последова-
тельность вычисления операндов, то множественные вычисления
в одной конструкции не содержат опасности неоднозначности:

sum = (i = 3, i++, i++); // так можно: sum = 4, i = 5

Каждое под-выражение или выражение с запятыми вычисля-
ется слева-направо, и все выражение в целом вычисляется по-
направлению к самому правому значению.

Turbo C++ перегруппирует выражения, реорганизовывая ас-
социативные и коммутативные операции независимо от наличия
круглых скобок, с тем, чтобы получить эффективно компилируе-
мое выражение; реорганизация выражения ни в коем случае не
влияет на результатвычисления выражения.

Круглые скобки можно использовать для того, чтобы при-
нудительно задать порядок вычислений в выражении. Например,
если имеются переменные a, b, c и f, то выражение f=a+(b+c)
вызывает сначала вычисление (b+c), а затем уже сложение ре-
зультата с a.

Ошибки и переполнения

Во время вычисления выражения Turbo C++ может встретить
многие проблематичные ситуации, как то деление на ноль или
получение значений с плавающей точкой, выходящих за пределы
допустимого диапазона. Переполнение целочисленных значений
игнорируется (С использует арифметические действия по модулю
2 в n-разрядных регистрах), однако ошибки, обнаруживаемые
математическими библиотечными функциями, могут обрабатывать-
ся стандартными или определяемыми пользователем подпрограм-
мами. См. matherr и signal в Справочнике по Библиотеке.

— 76 —
Семантика операций

Описанные здесь операции Turbo C++ являются операциями
стандарта ANSI C.

Если операции не перегружены, то следующая информация
действительна как для С, так и для С++. В С++ вы можете пе-
регрузить все эти операции, за исключением операции . (опе-
рация задания компонента) и ?: (условная операция) (также не
могут быть перегружены операции С++ :: и .*).

Если операция перегружена, то приводимые здесь сведени-
ядля нее недействительны.Таблица 1.19 на стр.74 оригинала
приводит синтаксис для всех операций и выражений с операция-
ми.
Постфиксные и префиксные операции

Шесть постфиксных операций [] () . -> ++и — использу-
ются для построения постфиксных выражений, показанных в таб-
лице синтаксиса выражений (таблица 1.19). Операции
инкремента и декремента (++ и —) также являются префиксными
и унарными операциями;они обсуждаются, начиная со стр.79
оригинала.

Операция индексации массива [] —————————

В выражении

постфиксное-выражение [выражение]

в С, но не обязательно в С++, выражение выраж1[выраж2]
определяется как

*((выраж1) + (выраж2))

где либо выраж1 это указатель, а выраж2 это целочислен-
ное значение, либо выраж1 это это целочисленное значение, а
выраж1 это указатель. (Каждый из пунктуаторов [], * и + мо-
жет быть перегружен в С++).

Операция вызова функции ()

Выражение

постфиксное-выражение()

представляет собой вызов функции, задаваемой постфикс-
ным выражением. Список-аргументов-выражения — это разделяе-
мый запятой список выражения любого типа, задающий
фактические (или действительные) аргументы функции. Значение
самого выражения вызова функции, если оно вообще имеет мес-
то, определяется оператором возврата в определении функции.
См. «Вызовы функций и преобразования аргументов» на стр.63
оригинала, где приводится более поробное изложение вызова
функций.

Операция задания компонента структуры/объединения . (точка)

В выражении

постфиксное-выражение . идетификатор

постфиксное-выражениедолжно иметь тип структуры или
объединения; идентификатор должен являться именем компонента
данной структуры или объединения. Выражение обозначает объ-
ект — компонент структуры или объединения. Значением данного
выражения будет являться значение выбранного таким образом
компонента; оно будет являться именующим выражением (lvalue)

— 77 —
в том и только том случае, если именующим выражением являет-
ся само постфиксное выражение. Подробное описание использо-
вания операций . и -> дается на стр.66 оригинала.

Именующие выражения определяются на стр.28 оригинала.

Операция указателя структуры/объединения ->

В выражении

постфиксное-выражение -> идентификатор

должно иметьтип указателя структуры или указателя объ-
единения; идентификатор же должен быть именем компонента
этой структурыили объединения. Выражение обозначает объект —
компонент структуры или объединения. Значением данного выра-
жения будет являться значение выбранного таким образом ком-
понента; оно будет являться именующим выражением (lvalue) в
том и только том случае, если именующим выражением является
само постфиксное выражение.

Операция постфиксного инкремента ++

В выражении

постфиксное-выражение++
операндом является постфиксное выражение:
оно должно быть скалярного типа (арифметического или
типа указателя) и должно являться модифицируемым именующим
выражением (более подробная информация об именующих выраже-
ниях приводится на стр.28 оригинала.) Постфикс ++ также на-
зывают операцией постинкремента. Значением всего выражения
является значение постфиксного выражения до выполнения инк-
ремента. После вычисления постфиксного выражения операнд ин-
крементируется на 1.

Величина инкремента зависит от типа операнда. Значения
типа указателя вычисляются по правилам арифметических дейс-
твий с указателями.

Постфиксная операция декремента —

Постфиксная операция декремента, также известная как
постдекремент, подчиняется тем же правилам, что и операция
постфиксного инкремента, за исключением того, что единица
после вычислениявыражения вычитается.

Операции инкремента и декремента

Первыми двумя унарными операциями являются операции ++
и —. Эти операции бывают как постфиксными, так и префиксны-
ми, и поэтому обсуждаются в данногмразделе. Затем рассматри-
ваются остальные шесть префиксных операций.

Операция префиксного инкремента ++

В выражении

++ унарное-выражение

операндом является унарное выражение:
оно должно быть скалярного типа (арифметического или
типа указателя) и должно являться модифицируемым именующим
выражением. Операцию префиксного инкремента также называют
операцией преинкремента. Операнд инкрементируется на 1 до
вычисления выражения; значением всего выражения является ин-
крементированное значение операнда. Величина инкремента за-

— 78 —
висит от типа операнда. Значения типа указателя вычисляются
по правилам арифметических действий с указателями.

Префиксная операция декремента —

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

i = 3.0e3; // double i в контексте и видима
// int i в контексте, но скрыта
ch = ‘A’; // char ch в контексте и видима
*)
// double i вне контекста
i += 1; // int i видима и равна 4
… // char ch все еще в контексте и видима
// и равна ‘A’
*)
… // int i и char ch вне контекста

И снова, специальные правила действуют в отношение
скрытых имен классов и имен компонентов классов: специальные
операции С++ позволяют доступ к скрытымидентификаторам при
определенных условиях (см. стр.103 оригинала).

Продолжительность

Продолжительность, близко связаннаяс классом памяти,
определяет продолжительность периода, в течение которого
объявленным идентификаторам соответствуют распределенные в
памяти реальные физические объекты. Такжеделается различие
между объектами времени компиляции и времени выполнения.
Например, переменным, в отличие от определяемых типов
(typedefs) и типов, память непосредственно во время выполне-
ния не распределяется. Существует три вида продолжительнос-
ти: статическая, локальная и динамическая.

Статическая продолжительность (static)

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

— 32 —

При отсутствии явного инициализатора, либо вС++ конс-
труктора, объекты со статической продолжительностью инициа-
лизируются в ноль (или пустое значение).

Статическую продолжительность не следует путать с фай-
ловым или глобальным контекстом. Объектможетиметьстатическую
продолжительность и при этом локальный контекст.

Локальная продолжительность (local)

Объект с локальной продолжительностью всегда имеет ло-
кальный контекст, поскольку он не существует вне своего объ-
емлющего блока. Обратное неверно: объект слокальным контекс-
том может иметь статическую продолжительность.

Объектыс локальнойпродолжительностью жизни, иначе
называемые динамическими локальнымипеременными, менее надеж-
ны. Они создаются в стеке (или в регистре) при входе в объ-
емлющий их блок или функцию. При выходе программы из такого
блока или функции они уничтожаются. Объекты с локальной про-
должительностью должны быть инициализированы явно;в против-
ном случае их исходное содержимое непредсказуемо. Объекты с
локальной продолжительностью всегда должны иметь локальный
контекст или контекст функции.При объявлении переменных ло-
кальной продолжительности можно использовать спецификатор
класса памяти auto, однако он является избыточным, поскольку
auto для переменных, объявленных в блоке, всегда является
умолчанием.

При объявлении переменных (например, int, char, float)
спецификатор класса памяти register такжеподразумевает auto,
однако компилятору при этом передается запрос (или рекомен-
дация) о том, что при возможности данный объект желательно
разместить в регистре. Turbo C++можно установить таким обра-
зом, чтобы он распределял регистрлокальной интегральной пе-
ременнойили переменной типа указатель, если какой-либо ре-
гистр свободен. Если свободных регистров нет, то переменная
распределяется как auto, или динамический локальный объект,
без выдачи предупреждения или генерации ошибки.

Динамическая продолжительность (dynamic)

Объекты с динамической продолжительностью жизни созда-
ются и разрушаются конкретными вызовами функций при выполне-
нии программы. Им распределяется памятьиз специального ре-
зерва памяти, называемого кучей, при помощи либо стандартных
библиотечных функций, какнапример malloc, либо при помощи
операции С++ new. Соответствующая отмена распределения вы-
полняется при помощи free или delete.

Единицы трансляции

Термин единица трансляции относится к файлу исходного
кода вместе с включаемыми файлами, но безисходных строк,
опущенных условными директивами препроцессора. Синтаксически
единица трансляции определяется как последовательность внеш-
них объявлений:

единица-трансляции:
внешнее-объявление
единица-трансляции внешнее-объявление

внешнее-объявление:
определение-функции
объявление

— 33 —
Слово external имеет в С несколько значений; в данном
случае оно относится к объявлениям, находящимся вне ка-
ких-либо функций, и которые, следовательно, имеют контекст
файла. (Отдельным свойством является внешний тип компоновки;
см.следующий раздел, «Компоновка».) Любое объявление, также
резервирующее память для объекта или функции, называется оп-
ределением (или объявлением определения). Более подробную
информацию см. в разделе «Внешние объявления и определения»
на стр.36 оригинала.

Компоновка

Выполняемая программа обычно создается компиляцией нес-
кольких независимых единиц трансляции, а затем компоновкой
получившихся объектных файлов с уже существующими библиоте-
ками. Проблема возникает, когда один и тот же идентификатор
объявлен в разных контекстах (например, в различных файлах),
либо объявлен более одного раза в одном и том же контексте.
Компоновка это процесс, который позволяетправильно связать-
каждое вхождение идентификатора с одним конкретным объектом
или функцией. Все идентификаторы имеют один из трех атрибу-
товкомпоновки, тесно связанных с их контекстом: внешняя ком-
поновка, внутренняя компоновка или отсутствие компоновки.
Эти атрибуты определяются местоположением и форматом объяв-
лений, а также явным (или неявным по умолчанию) использова-
нием спецификатора класса памяти static или extern.

Каждое вхождение конкретного идентификатора с типом
компоновки external представляет тот же самый объект или
функцию во всем множестве файлов и библиотек, составляющих
программу. Каждое вхождение конкретного идентификатора с ти-
пом компоновки internal представляет тот же самый объект или
функцию только в пределах одного файла. Идентификаторы с ти-
пом компоновки no (отсутствие) представляет уникальные эле-
менты программы.

Ниже приводятсяправила внешней (external) и внутренней
(internal) компоновки:

1. Любой идентификатор объекта или файла, имеющий фай-
ловый контекст, будет иметь внутренний тип компоновки, если
его объявление содержит спецификатор класса памяти static.

Для С, если один и тот же идентификатор в пределах од-
ного файла появляется и с внутренним, и с внешним типом ком-
поновки, то идентификатор будет иметь внутренний тип компо-
новки.

2. Если объявление идентификатора объекта или функции
содержит спецификатор класса памяти extern, то идентификатор
имеет тот же тип компоновки, что и видимое объявление иден-
тификатора с файловым контекстом. Если такого видимого объ-
явления не имеется, то идентификатор будет иметь внешний тип
компоновки.

3. Если функция объявлена без спецификатора класса па-
мяти, то ее тип компоновки определяется, как если бы был ис-
пользован спецификатор класса памяти extern.

4. Если идентификатор объекта с файловым контекстом
объявлен без спецификатора класса памяти, то идентификатор
имеет внешний тип компоновки.

Следующие идентификаторы не имеют атрибута типа компо-
новки:

1. Любой идентификатор, объявленный иначе, чем объект

— 34 —
или функция (например, идентификатор typedef).

2. Параметры функции.

3. Идентификаторы с контекстом блока в случае объектов,
объявленных без спецификатора класса памяти extern.

Синтаксис объявления

Все шесть взаимосвязанных атрибута (класс памяти, тип,
контекст, видимость,продолжительность и тип компоновки) мо-
гут быть разными способами определены при помощи объявлений.

Объявления могут быть объявлениями определения(их обыч-
но просто называют объявлениями) и объявлениями ссылки
(иногда называемыми неопределяющими объявлениями). Объявле-
ние определения, как и следует из названия, выполняет две
функции, объявления и определения; неопределяющие же объяв-

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

Префиксная операция декремента, также известная как
предекремент, имеет следующий синтаксис:

—унарное-выражение

и подчиняется тем же правилам, что и операция префикс-
ного инкремента, за исключением того, что единица перед вы-
числением выражения вычитается.

Унарные операции

Существует шесть унарных операций (кроме ++ и —):
. * + — тильда и !. Их синтаксис:

унарная-операция выражение-приведения

выражение-приведения:
унарное-выражение
(имя-типа) выражение-приведения

Операция адресации &

Символ & также используется в С++ для задания ссылочных
типов данных. См. стр.98 оригинала.

Операции& и * (операция * описана в следующем разделе)
используются совместно в качестве операций установки ссылки
и ображения по ссылке (разыменования). В выражении

& выражение-приведения

операнд выражение-приведениядолженявляться либо обозна-
чением функции, либо именующим выражением, обозначающим объ-
ект, не являющийся битовымполем и не имеющий спецификатор
класса памяти register. Если операнд имеет некоторый тип
type, то результатом операции будет указатель на type.

Отметим, что некоторые не являющиеся именующим выраже-
нием идентификаторы, такие как имена функций и имена масси-
вов, автоматически преобразовываются в определенном контекс-
те к типу «указатель на X». Операцию & использовать с такими
объектами можно, но такая операция будет являться избыточной
и будет отменена компилятором.

Рассмотрим следующий фрагмент:

type t1 =1, t2 = 2;
type *ptr = &t1; // инициализированный указатель
*ptr = t2; // тот же эффект, что и t1 = t2

Отметим, что type *ptr = &t1 обрабатывается как

T *ptr;
ptr = &t1;

так что присваивается не *ptr, а ptr. После инициализа-
ции ptrадресом&t1 его можно использовать для обращения по
ссылке и получить именующее выражение *ptr.

Операция обращения по ссылке *

В выражении

— 79 —

* выражение-приведения

операнд выражение-приведения должен иметь тип «указа-
тель на type», где type это любой тип. Результатом обращения
по ссылке имееттип type.Если операнд имеет тип «указатель
функции», то результатом будет являться обозначение функции;
если операндом является указатель на объект, то результатом
будет именующее выражение, обозначающее данный объект. В
следующих ситуациях результат обращения по ссылке неопреде-
лен:

1. Выражение-приведения это пустой (null) указатель.
2. Выражение-приведения это адрес динамической локаль-
ной переменной, а выполнение объемлющего блока уже заверше-
но.

Унарная операция плюс +

В выражении

+выражение-приведения

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

Унврная операция минус —

В выражении

-выражение-приведения

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

Операция поразрядного дополнения (тильда)

В выражении

выражение-приведения

операнд выражение-приведения должен быть интегрального
типа.Результатом является поразрядное дополнение операнда
после любых требуемых интегральных действий. Каждый бит со
значением 0 устанавливается в 1, а каждый единичный бит опе-
ранда устанавливается в 0.

Операция логического отрицания !

В выражении

!выражение-приведения

операнд выражение-приведения должен быть скалярного ти-
па. Результат иммет тип int и представляет собой логическое
отрицание операнда: 0 при ненулевом операнде и 1 в случае
нулевого операнда. Выражение !E эквивалентно выражению (0 ==
Е).
Операция sizeof

Существует два раздельных способа использования опера-
ции sizeof:

sizeof унарное-выражение
sizeof (имя-типа)

— 80 —

Размер выделяемой для каждого типа памяти зависит от
конкретной машины.

В обоихсучаяхрезультат представляет собой целочисленную
константу, выражающую размер в байтах областипамяти, занима-
емой операндом (определяемый за некоторыми исключениями ти-
пом операнда). В первом случае тип выражения операнда опре-
деляется без расчета выражения (и следовательно, без
побочных эффектов). Если операнд имеет тип char (signed или
unsigned), то операция sizeof дает в результате1. Если опе-
ранд не является параметром и имеет тип масива, то результат
представляет собой общее количество байтов в массиве (други-
ми словами, имя массива не преобразовавается к типу указате-
ля). Число элементов массива равно sizeof массив/sizeof мас-
сив[0].
Если операнд является параметром, объявленным как
массив или функция, sizeof дает размер указателя. Примени-
тельно к структурам и объединениям sizeof дает общее число
байтов, включающее любые символы-заполнители.

Целочисленный тип результата операцииsizeof называется
size_t, определенный как unsigned int в stddef.h.

Можно использовать sizeof в директивах препроцессора;
это особенность Turbo C++.

C++: В С++ sizeof(тип класса), где тип класса является
производным от какого-либо базового класса, возвращает раз-
мер базового класса.

Операции типа умножения

Существует три операции типа умножения: * / и %. Син-
таксис этих операций следующий:

выражение-типа-умножения:
выражение-приведения
выражение-типа-умножения * выражение-приведения
выражение-типа-умножения / выражение-приведения
выражение-типа-умножения % выражение-приведения

Операнды операций * (умножения) и / (деления) должны
быть арифметического типа. Операнды операции % (деление по
модулю,или остаток) должны быть интегрального типа. С опе-
рандами выполняются обычные арифметические преобразования
(см. стр.41 оригинала).
Результатом выполнения операции (операнд1 * операнд2)
является произведение двух операндов. Результатами операций
(операнд1 / операнд2) и (операнд1 % операнд2) являются част-
ное и остаток от деления, соответственно, где операнд1 де-
лится на операнд2, при условии, что операнд2 не равен нулю.
Использование операций / и % с нулевым делителем дает ошиб-
ку.

Если операнд1 и операнд2 имеют целочисленный тип, а
частное не является целым, то результаты операции следующие:

1. Если операнд1 и операнд2 имеют одинаковый знак, то
операнд1/ операнд2 есть наибольшее целое, меньшее чем истин-
ное частное, а операнд1 % операнд2 имеет тот же знак, что и
операнд1.

2. Если операнд1 и операнд2 имеют разные знаки, то опе-
ранд1/ операнд2 есть наименьшее целое, большее чем истинное-
частное, а операнд1 % операнд2 имеет тот же знак, что и опе-
ранд1.

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

ления требуют наличия где-либо далеев программе определений.
Объявление ссылки просто вводит в программу одно или более
имен идентификаторов.Определение фактически распределяет
объекту память и связывает идентификатор с этим объектом.

Предварительные определения

СтандартANSI C вводит новуюконцепцию: предварительное
определение. Любое объявление внешних данных, не имеющее
спецификаторакласса памяти и инициализатора, рассматривается
как предварительное определение. Еслиобъявленный идентифика-
тор появляется в последующемопределении, то предварительное
определение рассматривается,как если бы имелся спецификатор
класса памяти extern .Другими словами, предварительное опре-
деление становится простым объявлением ссылки.

Если достигнут конец единицы трансляции, а для иденти-
фикатора так и не было встречено определения с инициализато-
ром, то предварительное определение становится полным
определением, а для определенного таким образом объекта ре-
зервируется неинициализированная (заполненнаянулями) область
памяти. Например,

int x;
int x; /* допустимо, резервируется одна копия x */

int y;
int y = 4; /* допустимо, y инициализируется значением 4 */

int z = 5;
int z = 6; /* недопустимо, т.к. оба определения
инициализированы */
Возможные объявления

В число объектов, которые могут быть объявлены, входят:

— переменные
— функции
— классы и компоненты классов (С++)
— типы
— теги структур, объединений и перечислимых данных
— компоненты структур
— компоненты объединений
— массивы прочих типов
— перечислимые константы
— метки операторов
— макросы препроцессора

Полный синтаксис объявлений показан в следующих табли-

— 35 —
цах. Рекурсивная природа синтаксиса описателей позволяет
создавать сложные описатели. Для улучшения читаемости мы
пошли на использование определяемого типа (typedef).

Синтаксис объявлений Turbo C++ Таблица 1.10
————————————————————
объявление:

объявление-asm
объявление-функции
спецификация-типа-компоновки

спецификатор-объявления:
спецификатор-класса-памяти
спецификатор-типа
спецификатор-функции
friend (только для С++)
typedef

спецификаторы-объявления:
спецификатор-объявления

спецификатор-класса-памяти:
auto
register
static
extern

спецификатор-функции: (только для С++)
inline
virtual

спецификатор-типа:
имя-простого-типа
спецификатор-класса
спецификатор-перечислимых-данных
спецификатор-усовершенствованного-типа
const
volatile

имя-простого-типа:
имя-класса
имя-typedef
char
short
int

long
signed
unsigned
float
double
void

спецификатор-усовершенствованного-типа:
ключ-класса идентификатор
ключ-класса имя-класса
enum имя-перечислимых-данных

ключ-класса: (только для С++)
class
struct
union

список-перечислимых-данных:
нумератор
список-нумераторовнумератор

— 36 —
нумератор:
идентификатор
идентификатор = выражение-типа-константы

выражение-типа-константы:
условное-выражение

спецификация-типа-компоновки: (только для С++)
extern строка (* *)
extern строка объявление

список-объявления:
объявление
список-объявления объявление
————————————————————

Для следующей таблицы отметим, что на количество и по-
рядок модификаторов и квалификаторов наложены ограничения.
Кроме того, перечисленные модификаторыявляются единственным-
дополнением синтаксиса декларатора, не входящим в стандарт
ANSI C и С++. Каждый модификатор подробно описан, начиная со
стр.46 оригинала.

Синтаксис декларатора Turbo C++ Таблица 1.11
————————————————————
список-декларатора:
инициализатор-декларатор
список-декларатораинициализатор-декларатор

инициализатор-декларатор:
имя-декларатора
список-модификаторов
операция-указателядекларатор
декларатор (список-объявления-параметров)

(список-со-квалификаторов — только для С++)
декларатор []

список-модификаторов:
модификатор
список-модификаторов модификатор

модификатор:
cdecl
pascal
interrupt
near
far
huge

операция-указателя:
*
& (только для С++)
имя-класса = * (только для C++)

список-со-квалификаторов:
со-квалификатор

со-квалификатор:
const
volatile

имя-декларатора:
имя
имя-класса (только для С++)
имя-класса (только для С++)
имя-typedef

— 37 —

имя-типа:
спецификатор-типа

абстрактный-декларатор:
операция-указателя
(список-аргументов-объявления)

[]

список-объявления-аргументов:

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Turbo C++ Version 1.0 Programmer’s Guide

КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

— 81 —

Округление всегда выполняется к нулю.
Операции типа сложения

Существует две операции типа сложения: + и -. Синтаксис
этих операций следующий:

выражение-типа-сложения:
выражение-типа-умножения
выражение-типа-сложения + выражение-типа-умножения
выражение-типа-сложения — выражение-типа-умножения

Операция сложения +

Допустимыми являются следующие типы операндов выражения
операнд1 + операнд2:

1. Операнд1 и операнд2 оба арифметического типа.

2. Операнд1 интегрального типа, а операнд2 является
указателем на объект.

3. Операнд2 интегрального типа, а операнд1 является
указателем на объект.

В первом случае выполняются стандартные арифметические
преобразования операндов, а результатом является их арифме-
тическая сумма. В случаях 2 и 3 применяются правила арифме-
тических действий с указателями. (Арифметические действия с
указателями рассматриваются на стр.57 оригинала).

Операция вычитания —

Допустимыми являются следующие типы операндов выражения
операнд1 — операнд2:

1. Операнд1 и операнд2 оба арифметического типа.

2. Оба операнда являются указателями на совместимые ти-
пы объектов. (Примечание: неквалифицированный тип type расс-
матривается как совместимый с квалифицированными типами
const type, volatile type и const volatile type.)

3. Операнд2 интегрального типа, а операнд1 является
указателем на объект.

В первом случае выполняются стандартные арифметические
преобразования операндов, а результатом является их арифме-
тическая разность. В случаях 2 и 3 применяются правила ариф-
метических действий с указателями.

Операции поразрядного сдвига

Существует две операции поразрядного сдвига: >.
Синтаксис этих операций следующий:

выражение-типа-сдвига:
выражение-типа-сложения
выражение-типа-сдвига > выражение типа сдвига

Операция поразрядного сдвига влево > E2 операнды Е1 и Е2 должны иметь тип
int. С Е1 и Е2 выполняются обычные целочисленные действия, а
тип результата определяется операндом Е1. Если Е2 отрицате-
лен, либо по числу разрядов больше или равен Е1, то операция
неопределена.

Результатом операции E1 >> E2 является значение E1,
сдвинутое вправо на Е2 разрядов. Если Е1 имеет тип unsigned,

то при необходимости происходит его заполнение нулями слева.
Если же Е1 имеет тип signed, то заполнение слева выполняется
знаком (0 для положительных и 1 для отрицательных значений).
Такое расширение знакового бита гарантирует, что знак у Е1
>> E2 будет таким же, как и у E1. За исключением типов со
знаком, значение E1 >> E2 представляет собой целую часть
частного.

Операции отношения

Существует четыре операции отношения: < > =. Син-
таксис этих операций следующий:

выражение-отношения:
выражение-типа-сдвига
выражение-отношения < выражение-типа-сдвига выражение-отношения > выражение-типа-сдвига
выражение-отношения =выражение-типа-сдвига

Операция меньше чем < В выражении E1 < E2 операнды должны удовлетворять одно- му из следующего набора условий: 1. Оба значения Е1 и Е2 - арифметического типа. 2. Оба значения Е1 и Е2 являются указателями квалифици- рованных или неквалифицированных версий совместимых типов объектов. Определение квалифицированных имен дается на стр.108 оригинала. 3. Оба значения Е1 и Е2 являются указателями квалифици- рованных или неквалифицированных версий совместимых неполных типов. В случае 1 выполняются обычные арифметические преобра- зования. Результат E1 < E2 имеет тип int. Если значение E1 меньше значения E2, то результат равен 1 (истина); в против- - 83 - ном случае результат равен 0 (ложь). В случаях 2 и 3, где Е1 и Е2 являются указателями сов- местимых типов, результат операции E1 E2 дает 1 (истина), если значение Е1 больше значения Е2;в противном случае результат равен 0 (ложь), причем используются те же способы интерпретации арифметических сравнений и сравнений указателей, что опреде- лены для операции "больше чем". К операндам применимы те же правила и ограничения. Операция меньше или равно = E2 дает 1 (истина), если значение Е1 больше или равно значению Е2. В противном случае результат равен 0 (ложь), причем используются те же способы интерпретации арифметических сравнений и сравнений указате- лей, что определены для операции "меньше чем". К операндам применимы те же правила и ограничения. Операции типа равенства Существует две операции типа равенства: == и !=. Они проверяют условие равенства операндов арифметического типа и типа указателей, следуя при этом правилам, аналогичным тем, что действуют для операцийотношения. Отметим, однако, что == и != имеют более низкий приоритет выполнения, чем операции отношения , =. Кроме того, операции == и != позво- ляют выполнять проверку равенства указателей в таких случа- ях, где операции отношения неприменимы. Синтаксис этих опе- раций следующий: выражение-типа-равенства:

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30