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

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

Turbo C++ Version 1.0 Programmer’s Guide

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

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

слова, идентификаторы, константы, строковые литералы, опера-
ции и знаки пунктуации (также называемые разделителями).
Формальное описание лексемы имеет следующий вид:

лексема:
ключевое слово
идентификатор
константа
строковый литерал
операция
знак пунктуации

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

Ключевые слова

Ключевыми словами называются слова, зарезервированныед-
ля специальных целей, которые не должны использоваться в ка-
честве обычных имен идентификаторов. В следующих двух табли-
цах приводятся ключевые слова Turbo C++. Вы можете
использовать опции компилятора командной строки (или опции в
IDE), чтобы выбрать только ключевые словаANSI, ключевые сло-
ва UNIX и т.д. Информацию об этих опциях см. в главах 1,
«Справочник IDE», и 4, «Компилятор командной строки» в Руко-
водстве пользователя.

Все ключевые слова Turbo C++ Таблица 1.1
————————————————————
asm _ds interrupt short
auto else _loadds signed
break enum long sizeof
case _es near _ss
catch _export new static
cdecl extern operator struct
char far pascal switch
class float private template
const for protected this
continue friend public typedef
_cs goto register union
default huge _regparam unsigned
delete if return virtual
do inline _saverages void
double int _seg volatile
while
————————————————————

Расширения Turbo C++ относительно ANSI C Таблица 1.2
————————————————————
cdecl _export _loadds _saveregs
_cs far near _seg
_ds huge pascal _ss
_es interrupt _regparam
————————————————————

— 12 —

Ключевые слова, специфичные для C++ Таблица 1.3
————————————————————
catch friend operator public
class inline private template
delete new protected this
virtual
————————————————————

Регистровые псевдопеременные Turbo C++ Таблица 1.4
————————————————————
_AH _BL _CL _DL
_AL _BP _CX _DX
_AX _BX _DH _FLAGS
_BH _CH _DI _SI
_SP
————————————————————
Идентификаторы

Формальное определение идентификатора имеет следующий вид:

идентификатор:
не-цифра
идентификатор не-цифра
идентификатор цифра

не-цифра: одно из
a b c d e f g h i j k l m n o p q r s t u v w x y z _
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

цифра: одно из
0 1 2 3 4 5 6 7 8 9

Ограничения состава и длины идентификаторов

Идентификаторы представляют собой произвольные имена
любой длины, присваиваемыеклассам, объектам, функциям,пере-
менным, определяемым пользователем типам данных ит.д. Иден-
тификаторы могут содержать буквы от A до Z и от a до z, сим-
вол подчеркивания (_) и цифры от 0 до 9. Существует только
два ограничения:

1. Первый символ должен являться буквой или символом
подчеркивания.

Отметим, что идентификаторы в Turbo C++ значимы до лю-
бой длины.

2. По умолчанию Turbo C++ распознает только первые 32
символа в качестве значимых. Число значимых символов может
быть уменьшено при помощи меню или опций командной строки,
но не может быть увеличено. Используйте опцию -In TCC, либо
опцию меню O\!C\!S\!Identifier Length, где 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

Ссылочные типы создают алиасы объектов и позволяют переда-
вать функциям аргументы по ссылке. Традиционно передача ар-
гументов в С выполняется только по значению. В С++ переда-
вать аргументы можно как по значению, так и по ссылке.
Полную информацию см. в разделе «Ссылки» на стр.98 оригина-
ла.
Массивы

Данный раздел начинает часть главы, посвященную расс-
мотрению грамматики структуры фраз языка; описание различий
между грамматическими правилами лексики и структуры фраз
языка см. на стр.4.

Объявление

type декларатор []

объявляет масив, состоящий из элементов типа type. Мас-
сив в С состоит из непрерывной области памяти, по размеру
позволяющей в точности разместить все его элементы.

Если в деклараторе массива задано выражение, то при
еговычислении должна получаться положительная целочисленная
константа. Получившееся значение представляет собой число
элементов массива. Каждый из элементовмассива нумеруется от
0 до числа элементов массива, минус единица.

Многомерные массивы создаются путем объявления массивов
из элементов типа массив. Таким образом, двумерный массив из
пяти строк и семи столбцов с именем alpha объявляется следу-
ющим образом:

type alpha [5] [7];

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

— 58 —
Такой массив имеет неопределенный размер. Контекстом, где
допустимо такое положение, является тот случай, когдадля ре-
зервирования памяти размер массива не требуется. Например,
для объявление объекта типа массива extern точный размер
массива не требуется; не требуется он и при передаче функции
параметра типа массива. Будучи специальным расширением ANSI
C, Turbo C также позволяет объявлятьв качестве последнего
элемента структуры массив неопределенного размера. Такой
массив не увеличивает размера структуры, а для того, чтобы
обеспечить правильное выравнивание структуры, ее можно спе-
циально дополнить символами-заполнителями. Такие структуры
обычно используются при динамическом распределении памяти,
когда для правильного резервирования области памяти к разме-
ру структуры следует явно прибавить фактический размер необ-
ходимого массива.

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

Функции

Функции представляют собой центральный вопрос програм-
мирования на Turbo C++. Такие языки программирования, как
Паскаль, делают различие между процедурами и функциями. В
Turbo C++ функции играют обе роли.

Объявления и определения

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

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

В С++ вы должны всегда пользоваться прототипами функ-
ции. Мы рекомендуем также всегда использовать их и в С.

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

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

Объявления и прототипы

В оригинальном стиле объявлений Кернигэна и Ритчи функ-
ция могла быть либо объявлена неявно, по ее вызову, либо яв-
но:

func()

где type — это опциональный тип возврата, по умолчанию

— 59 —
равный int. Можно объявить функцию с любым типом возврата,
за исключениемтипов массива или функции. Такой подход не
позволяет компилятору контролировать соответствие типа или
количества используемыхпри вызове функции аргументов объяв-
лению.

Эта задача упрощается благодаря введению прототипа
функции со следующим синтаксисом объявления:

func(список-деклараторов-параметров)

При помощи IDE или опции компилятора командной строки
можно разрешить выдачу следующего предупреждения: «Function
called without a prototype» («Функция вызывается без прото-
типа»).

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

long lmax(long v1, long v2); /* прототип */
main()
(*
int limit = 32;
char ch = ‘A’;
long mval;
mval = lmax(limit,ch): /* вызов функции */

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

Прототипы функций также упрощают документирование кодов
программы. Например, функция strcpy принимает два параметра:
исходную строку и строку назначения. Вопрос, где какая из
них? Прототип функции

char *strcpy(char *dest, char *source);

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

Декларатор функции в круглых скобках, содержащий единс-
твенное словоvoid, указывает на функцию, вообще не
принимающую аргументов:

func(void);

В С++ func() также означает функцию, не принимающую ар-
гументов.

stdarg.h содержит макросы, которые можно использовать в
функциях, определяемых пользователем, с переменным числом

— 60 —
параметров.

Прототип функции обычно объявляет функцию, принимающую
фиксированное число параметров. Для функции С, принимающей
переменное число параметров (например, printf) прототип
функции может заканчиваться многоточием (…), например:

f(int *const, long total, …)

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

Ниже приводятся примеры деклараторов функций и прототипы:

int f(); /* В С это функция, возвращащая int, без ин-
формации о параметрах. Это «классический стиль» Кернигэна и
Ритчи */

int f(); /* В С++ это функция, не принимающая аргументов */

int f(void); /* Функция, возвращающая int и не принима-
ющая параметров */

Страницы: 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

— 14 —
восьмеричная-константа
шестнадцатиричная-константа

десятичная-константа:
цифра-кроме-нуля
десятичная-константа цифра

восьмеричная-константа:
0
восьмеричная-константа восьмеричная-цифра

шестнадцатиричная-константа:
0 x шестнадцатиричная-цифра
0 X шестнадцатиричная-цифра
шестнадцатиричная-константа шестнадцатиричная-цифра

цифра-кроме-нуля: одно из
1 2 3 4 5 6 7 8 9

восьмеричная-цифра: одно из
0 1 2 3 4 5 6 7

шестнадцатиричная-цифра: одно из
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F

суффикс-целочисленной-константы:
суффикс-константы-без-знака
суффикс-длинной-константы

суффикс-константы-без-знака: одно из
u U

суффикс-длинной-константы: одно из
l L

перечислимая-константа:
идентификатор

символьная-константа:
последовательность-символов-c

последовательность-символов-c:
символ-c
последовательность-символов-c символ-c

символ-c:
любой символ из исходного набора символов, за
исключением символов одинарной кавычки (‘), обратной наклон-
ной черты (\) или управляющей-последовательности символа но-
вой строки.

управляющая-последовательность: одно из
\* \’ \? \\
\a \b\f \n
\o \oo\ooo \r
\t \v\Xh… \xh…
————————————————————

Целочисленные константы

Целочисленные константы могут быть десятичными (основа-
ние системы счисления 10), восьмеричными (основание 8)или
шестнадцатиричными (основание 16). При отсутствии переопре-
деляющих суффиксов типданныхцелочисленной константы выводит-

— 15 —
ся из ее значения, как показано в таблице 1.6. Отметим, что
правила для десятичных и не-десятичных констант различны.

Десятичные константы

Допустимыми являются десятичные константы величиной от
0 до 4,294,967,295. Константы, выходящие за указанные преде-
лы, вызывают ошибку. Десятичныеконстанты не могут иметь ве-
дущие нули. Целочисленнаяконстанта с ведущим нулем рассмат-
риваетсякак восьмеричная. Таким образом,

int i = 10; /* десятичное 10 */
int i = 010; /* десятичное 8 */
int i = 0; /* десятичное 0 = восьмеричному 0! */

Отрицательные константы- это просто константы без
знака, к которым применена унарная операция минус.

Восьмеричные константы

Все константыс ведущим нулем рассматриваются как вось-
меричные.Если восьмеричная константа содержит недопустимые
цифры 8 или 9, выдается сообщение об ошибке. Ошибка будет
также выдаваться при превышении восьмеричной константой зна-
чения 037777777777.

Шестнадцатиричные константы

Все константы, начинающиеся с 0x (или 0X) рассматрива-
ются как шестнадцатиричные. Шестнадцатиричные константы,пре-
вышающие 0xFFFFFFFF, приводят к ошибке.

Суффиксы длинных констант и констант без знака

Если законстантой следует суффикс L (или l), то такая
константа будет представлена как длинная (типа long).Анало-
гичным образом, суффикс U (или u) делает константу констан-
той без знака (unsigned). Если численное значение константы
превышает десятичное 65,535, независимо от используемого ос-
нованиясистемы счисления, то такая константа будет иметь тип
unsigned long. Суффиксы можно указывать для одной и той же
константы в произвольном порядке и набирать в любом регист-
ре: ul, lu, UL и т.д.

Тип данных константы при отсутствии каких-либо суффик-
сов вообще (U, u, L или l) берется из следующей таблицы,пер-
выйже, который удовлетворяет требованиям величины этой
константы:

————————————————————
десятичная int, long int, unsigned long int
восьмеричная int, unsigned int, long int, unsigned long
int
шестнадцатиричная int, unsigned int, long int, unsigned
long int
————————————————————

Если константа имеет суффикс U или u, то ее тип данных
будет первым из типов unsigned int, insigned long int, кото-
рый удовлетворит требованиям ее величины.

Если константа имеет суффикс L или l, то ее тип данных
будет первым из типов long int, unsigned long int, который
удовлетворит требованиям ее величины.

Если константа имеет оба суффикса u и l (ul, lu, Ul,
lU,uL, Lu, LU или UL), то она будет иметь тип данных

— 16 —
unsigned long int.

В таблице 1.6 сведены представления целочисленных конс-
тант для всех трех систем счисления. Указанные типы данных
предполагают отсутствие переопределяющих суффиксов L или U.

Целочисленные константы Turbo C++ без L или U Таблица 1.6
————————————————————
Десятичные константы

0 до 32,767 int
32,768 до 2,147,483,647 long
2,147,483,648 до 4,294,967,295 unsigned long

> 4294967295 Генерируется ошибка

Восьмеричные константы

00 до 077777 int
0100000 до 0177777 unsigned int
02000000 до 017777777777 long
020000000000 до 037777777777 unsigned long

> 037777777777 Генерируется ошибка

Шестнадцатиричные константы

0x0000 до 0x7FFF int
0x8000 до 0xFFFF unsigned int
0x10000 до 0x7FFFFFFF long
0x80000000 до 0xFFFFFFFF unsigned long

> 0xFFFFFFFF Генерируется ошибка
————————————————————

Символьные константы

Символьная константа — этоодин или более символов, зак-
люченных в одинарные кавычки, например ‘F’, ‘=’, ‘\n’. В C
константы изодногосимвола имеюттип Int и имеют внутреннее
представление16 бит, в то времякак старший байт слова запол-
няется нулем или знаком. В C++ константа из одного символа
имеет тип char. Многосимвольные константы как в C, так и в C
++, имеют тип данных Int.

Управляющие последовательности

Для введения управляющих последовательностей,позволяю-
щих получить визуальное представление некоторых не имеющих
графическогоаналога символов, используется символ обратной
наклонной черты (\). Например, в качестве одного символа но-
вой строки можно записать константу \n.

Обратнаянаклонная черта используетсяс восьмеричными или
шестнадцатиричными числами для представления ASCII-символами
управляющего кода, соответствующемуэтому значению; например,
‘\03’ вместо Ctrl-C или ‘\x3F’ вместо вопросительного знака.
В управляющей последовательности может содержаться строка
длиной до трех восьмеричных илилюбое число шестнадцатиричных
цифр,при условии, чтоданноезначение лежит в допустимом для

Страницы: 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

int p(int,long) /* Функция с типомвозврата int,принима-
ющая два параметра, первый типа int, и второй типа long */

int pascal q(void); /* функция типа pascal, возвращаю-
щая int и не принимающая параметров */

char far *s(char *source, int kind); /* Функция,
возвращающая дальний указатель на char и принимающая два па-
раметра: превый — дальний указатель на char, а второй int */

int printf(char *format,…); /* Функция, возвращающая
int и принимающая фиксированный параметр типа указатель на
char и любое число дополнительных параметров неизвестного
типа */

int (*fp)(int); /* Указатель на функцию, возвращающую
int и принимающую один параметр int */

Объявления

Общий синтаксис для определений внешних функций приво-
дится в следующей таблице:

Определения внешних функций Таблица 1.18
————————————————————
файл:
внешнее-определение
файл внешнее-определение

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

определение-функции:
декларатор
составной-оператор
————————————————————

В целом, определение функции состоит из следующих раз-
делов (грамматика позволяет создание и более сложных конс-
трукций):

— 61 —
1. Опциональные спецификаторы класса памяти: extern или
static. Умолчанием является extern.

2. Тип возврата, возможно void. Умолчанием является
int.

Элементы из пунктов 1 и 2 можно взаимно комбинировать.

3. Опциональные модификаторы: pascal, cdecl, interrupt,
near, far, huge. Умолчание зависит от модели памяти и уста-
новленных опций компилятора.

4. Имя функции.

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

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

Объявления формальных параметров

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

int func(void) (* // аргументы отсутствуют

С++int func(T! t1, T2 t2, T3 t3=1) (*
// три простых параметра,
// один из которых с аргументо
// по умолчанию

C++int func(T1* ptr1, T2& tref) (*
// аргументы указатель и ссылк

int func(register int i) (* // запрос регистра для аргумен

int func(char *str,…) (* /* один строковый аргумент ипе-
ременное число прочих аргументов, либо фиксирован-
ное число аргументов с переменными типами */

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

Многоточие (…) означает, что функция будет вызываться в
разных случаях с различными наборами аргументов. Многоточие
может следовать за подсписком объявлений известных аргумен-
тов. Такая форма прототипа уменьшает число выполняемых ком-
пилятором проверок.

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

В деклараторах формальных параметров могут использоваться
модификаторы const и volatile.

Вызовы функций и преобразования аргументов

— 62 —

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

Ниже приводится краткое изложение правил, управляющих
обработкой в Turbo C++ модификаторов языка и формальных па-
раметров при вызове функций, как при наличии прототипа, так
и при его отсутствии:

1. Модификаторы языка для определения функции должны соот-
ветствовать модификаторам, используемым в объявлении функ-
ции, при всех вызовах функции.

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

Если ранее не был объявлен прототип функции, Turbo C++ пре-
образует интегральные аргументы при вызове функции в соот-
ветствии с правилами интегрального расширения, описанными в
разделе «Стандартные преобразования» на стр.41 оригинала.
При наличии в контексте прототипа функции Turbo C++ преобра-
зует данные аргументы к объявленным типам параметров, как
при операции присвоения.

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

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

Важное замечание

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

Структуры

Инициализация структуры описана на стр.42 оригинала.

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

— 63 —
далее ограничениями), и располагаться в любой последователь-
ности. Кроме того, компонент структуры может иметь тип бито-
вого поля, более нигде не разрешаемого. Тип струтуры в Turbo
C++ позволяет обрабатывать сложные структуры данных так же
легко, как и простые переменные.

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

Объявление структур выполняется при помощи ключевого

Страницы: 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

типа данных char диапазоне (от 0 до 0xff для Turbo C++).
Большие значения ведутк появлению ошибки компиляции «Numeric
constant too large» («числовая константа слишком велика»).
Например, восьмеричное число \777 больше максимально допус-
тимого значения \377, и вызовет генерирование ошибки. Первое
же не-восьмеричноеили не-шестнадцатиричное значение, встре-
ченное в восьмеричнойили шестнадцатиричной управляющей пос-

— 17 —
ледовательности, означает конец данной последовательности.

В исходной версии Turbo C допускалось только три цифры
шестнадцатиричной управляющей последовательности. Новые пра-
вила ANSI C, реализованные в Turbo C версии 2.0 и TurboC++,
могут вызвать проблемы со старыми кодами, предполагающими
преобразование только первых трех символов. Например, при
использовании версии Turbo C 1.x для определения строки со
звуковым сигналом (код ASCII 7), после которого следуют чис-
ловые символы, программист может написать:

printf(«\x0072.1Простая операционная система»);

Предполагается, что эта строка будет интерпретирована
как \x007 и «2.1Простая операционная система». Однако, Turbo
C++ (и TurboC версии 2.0) компилируют ее как шестнадцатирич-
ное число \x0072 и литеральную строку «.1Простая операцион-
ная система».

Чтобы избежать этих проблем, перепишитеваш код следую-
щим образом:

printf(«\x007» «2.1Простая операционная система»);

Неоднозначность может возникнуть также и в случае,
когда за восьмеричной управляющей последовательностью следу-
ет невосьмеричная цифра. Например, поскольку 8 и 9не являют-
ся допустимыми восьмеричными цифрами, константа \258 будет
интерпретирована какдвухсимвольнаяконстанта, составленная из
символов \25 и 8.

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

Управляющие последовательности Turbo C++ Таблица 1.7
————————————————————
Последовательность Значение СимволыВыполняемая функция
————————————————————
\a 0x07BELЗвуковой сигнал
\b 0x08BSЗабой
\f 0x0CFFПеревод бланка
\n 0x0ALFНовая строка (перевод строки)
\r 0x0DCRВозврат каретки
\t 0x09HTТабуляция (горизонтальная)
\v 0x0BVTВертикальная табуляция
\\ 0x5c\Обратная наклонная черта

Для фактического представления символа ASCII «обратная
наклонная черта», используемого например в команде DOS PATH,
следует записывать ее как \\.

\’ 0x27 ‘ Одинарная кавычка (апостроф)
\» 0x22 » Двойная кавычка
\? 0x3F ? Вопросительный знак
\OлюбыеO = строка до трех восьми-
ричных цифр
\xH любыеH = строка шестнадцатирич-
ных цифр
\XH любыеH = строка шестнадцатирич-
ных цифр
————————————————————

Специальные двух-символьные константы Turbo C++

Turbo C++ поддерживает также двух-символьные константы
(например, ‘An’, ‘\n\t’ и ‘\007\007’). Эти константы предс-

— 18 —
тавлены 16-битовыми значениями типаInt, где первый символ
расположен в младшем байте, а второй символ — в старшем бай-
те. Эти константы не могут быть перенесены на другие компи-
ляторы C.

Символьные константы со знаком и без знака

В C одно-символьные константы, такие как ‘A’, ‘\t’ и ‘\
007’, такжепредставлены 16-битовыми значениями типа Int. В
этом случае происходит расширение младшего байта в старший
байт по знаку; такимобразом, еслизначение превышает 127 (ос-
нование 10), то старший байт устанавливается равным -1
(=0xFF). Это свойство можно отменить, объявив, что по умол-
чанию тип char является unsigned (при помощи опции -R TCC,
либо выбором в меню Options \! Compiler \! CodeGeneration
опцию Unsigned Characters), чтоприведет к обнулению старшего
байта независимо от значения младшего байта.

Широкие символьные константы (только C)

Символьная константа, которой предшествует L, называет-
ся широкой символьнойконстантой и имеет тип данных wchar_t
(интегральный тип, определяемый в stdef.h). Например,

x = L ‘AB’;

Константы с плавающей точкой

Константа с плавающей точкой состоит из шести частей:

— десятичное целое
— десятичная точка
— десятичное дробное
— e или E и целочисленная экспонента со знаком (опционально)
— суффикс типа: f или F, либо l или L (опционально)

Десятичное целое или десятичное дробное (но не то и
другое) можно опустить. Можно опустить либо десятичную точ-
ку, либо букву e (или E) с целочисленной экспонентой со зна-
ком (но не то и другое). Эти правила позволяют выполнять за-
пись чисел как в обычной, так и в научной (экспоненциальной)
форме.

Отрицательные константыс плавающей точкой берутся как
положительные константы с префиксом — унарной операцией ми-
нус (-).

Примеры:
————————————-
Константа Значение
————————————-
6
23.45e6 23.45 x 10

.0 0

0. 0
0
1. 1.0 x 10 = 1.0

-1.23 -1.23
-5
2e-5 2.0 x 10
10
3E+10 3.0 x 10

— 19 —
34
.09E34 0.09 x 10
————————————-

Константы с плавающей точкой — типы данных

При отсутствии каких-либо суффиксов константы с плаваю-
щей точкой имеют тип данных double. Однако, вы можете прис-
воить константе с плавающей точкой тип данных float, добавив
к ней суффикс f или F. Аналогичным образом, суффиксl илиL
присвоит константе тип данных long double. В следующей таб-
лице показаны диапазоны значений, которые могут принимать
типы данных float, double и long double.

Размеры и диапазоны
констант с плавающей точкой Turbo C++ Таблица 1.8
————————————————————
Тип Размер (в битах) Диапазон значений
————————————————————
-38 38
float 32 3.4 x 10 до 3.4 x 10
-308 308
double 64 1.7 x 10 до 1.7 x 10
-4932 4932
long double 80 3.4 x 10 до 1.1 x 10
————————————————————
Перечислимые константы

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

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

enum team (* giants, cubs, dodgers *);

giants, cubs и dodgers это перечислимые константы типа
team, которые могут быть назначены любым переменным типа
team или любой другой переменной целочисленного типа. Значе-
ния, принимаемые перечислимыми константами,

giants = 0, cubs = 1, dodgers = 2

при условии отсутствия явных инициализаторов. В следую-
щем примере,

Страницы: 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

слова struct. Например,

struct mystruct (* … *); // mystruct — это тег струк-
туры

struct mystruct s, *ps, arrs[10];
/* s имеет тип структуры mystruct; ps это указатель на
тип struct mystruct */
Структуры без тегов и определения типов (typedef)

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

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

struct (* …*) s, *ps, arrs[10]; //структура без тега

При объявлении структуры, как с тегом, так и без него,
можно создать typedef:

typedef struct mystruct (* … *) MYSTRUCT;
MYSTRUCT s, *ps, arrs[10]; // то же, что и
// struct mystruct s и т.д.
typedef struct (* … *) YRSTRUCT; // тег отсутствует
YRSTRUCT y, *yp, arry[20];

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

Объявления компонентов структуры

Список-объявления-компонентов вфигурных скобках объяв-
ляет типы и имена компонентов структуры при помощи синтакси-
са декларатора, показанного в таблице 1.11 на стр.36
оригинала.

Компоненты структуры могут быть любого типа, за двумя
исключениями

1. Тип компонента не может быть тот же, что и объявляе-
мая в текущий момент структура:

struct mystruct (* mystruct s *) s1, s2;// недопустимо

Компонент структуры может являться указателем на объяв-

— 64 —
ляемую структуру, как в следующем примере:

struct mystruct (* mystruct *ps *) s1, s2; // так можно

Кроме того, структура может содержать ранее объявленные
типы структур, объявляя вхождения объявленных ранее струк-
тур.

В С++ ключевое слово struct может быть опущено.

2. Кроме С++, компонент структуры нигде не может иметь
тип «функция, возвращающая …», но тип «указатель на функ-
цию, возвращающую …» допустим. В С++ struct может иметь
компоненты-функции.

Структуры и функции

Функция может иметь возвращаемое значение типа структу-
ры или указателя структуры.

mystruct func1(void); // func1() возвращает структуру
mystruct
*func29void); // func2() возвращает указатель структуры

Структура можетбыть передана функции в качестве аргу-
мента, следующим образом:

void func1 (mystruct s); // непосредственно
void func2 (mystruct *sptr); // через указатель
void func3 (mystruct &sref); // по ссылке (только С++)
Доступ к компоненту структуры

Доступ к компонентам структур и объединений выполняется
операторами выбора . и ->. Предположим, что объект имеет тип
структуры S, а sptr это указатель на S. Тогда, если m это
идентификатор типа M, объявленного в S, то выражения s.m и
sptr->m имеют тип M и представляют объект m — компонент
структуры s. Выражение s->sptr является удобным синонимом (*
sptr).m.

Операция . называется прямым селектором компонента
структуры; операция -> называется косвенным селектором ком-
понента (или указателем) структуры; например,

struct mystruct (*

int i;
char str[21];
double d;
*) s, *sptr=&s;

s.i = 3; // присвоению члему i структуры mystruct s
sptr->d = 1.23; // присвоение компоненту d структуры
mystruct s

Выражение s.m является именуемым значением (lvalue),
если s это не именуемое значение и s не имеет тип массива.
Выражение sptr->m является именуемым выражением, если m не
имеет тип массива.
Если структура B содержит поле, тип которого есть
структура A, то доступ к компонентам A выполняется через два
одновременно задаваемых селектора компонента структуры:

— 65 —

struct A (*
int j;
double x;
*)

struct B (*
int i;
struct A a;
double d;
*) s, *sptr;

s.i = 3; // присвоение компоненту i структуры B s.a.j =
2; // присвоение компоненту j структуры A sptr->d = 1.23; //
присвоение компоненту d структуры B (sptr->).x = 3.14 //
присвоение компоненту x структуры A

Каждое объявление структуры вводит уникальный тип
структуры, поэтому в

struct A (*
int i,j;
double d;
*) a, a1;

struct B (*
int i,j;
double d;
*) b;

объекты a и a1 оба имеют тип struct A, но объекты a и b
имеют различные типы структуры. Структурам может выполняться
присваивание только в том случае, если и исходная структура,
и структура назначения имеют один и тот же тип:

a = a1;// так можно; тип один и тот же, поэтому может
быть // выполнено покомпонентное присвоение структур
a = b;// так нельзя; разные компоненты
a.1 = b.1; a.j = b.j; a.d = b.d; // однако присвоение
можно // выполнять на уровне компонентов структуры

Выравнивание по границе слова

Память распределяется структуре покомпонентно, сле-
ва-направо, от младшего к старшему адресу памяти. В следую-
щем примере

struct mystruct (*
int i;
char str[2];

double d;
*) s;

объект s занимает достаточное количество памяти для
размещения 2- байтового целочисленного значения, 21-байтовой
строки и 8-байтового значения типа double. Формат данного
объекта в памяти определяется опцией Turbo C++ выравнивания
по границе слова. Когда эта опция выключена (по умолчанию),
s будет занимать 31 байт непрерывно. Если же включить вырав-
нивание по границе слова опцией -a компилятора (или в диало-
говом поле Options \! Compiler \! Code Generation), то Turbo
C++ заполняет структуры байтами таким образом, что структура
была выравнена по следующим правилам:

— 66 —
1. Структура должна начинаться по границе слова (четный
адрес).

2. Любой не-символьный элемент будет иметь четное сме-
щение в байтах относительно начала структуры.

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

Страницы: 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

enum team (* giants, cubs=3, dodgers = giants + 1 *);

константы установлены следующим образом:

giants = 0, cubs = 3, dodgers = 1

Значения констант не обязаны быть уникальными:

enum team (* giants, cubs = 1, dodgers = cubs — 1 *);

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

Строковые литералы

— 20 —
Строковые литералы, известные также как строковые конс-
танты, образуют специальную категорию констант, используемых
для работы с фиксированными последовательностями символов.
Строковый литерал имееттип данных array ofchar и класспамя-
тиstatic, и записываетсякак последовательность произвольного
количества символов, заключенных в двойные кавычки:

«Это строковый литерал!»

Нулевая (пустая) строка записывается как «».

Символы внутри двойных кавычек могут включатьуправляю-
щие последовательности (см. стр. 13 оригинала). Например,
данный код,

«\t\t\»Имя \»\\\tАдрес\n\n»

распечатается следующим образом:

«Имя «\ Адрес

Слову «Имя » будет предшествовать два символа табуля-
ции; слову Адрес предшествуетодин символтабуляции. Строка
заканчиваетсядвумя символами новой строки. Последователь-
ность \» обеспечивает вывод внутренних кавычек.

Строка литерала хранится в памяти как заданная последо-
вательность символов,плюс конечный пустой символ (‘\0’). Ну-
левая строка хранится в виде одного символа ‘\0’.

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

#include

main()
(*
char *p;

p = «Это пример того, как Turbo C++»
» автоматически\nвыполняет для вас конкатенацию»
» очень длинных строк,\nчто позволяет получить»
» более красивые программы.»;
printf(*p*);
*)

На выходе программы будет:

Это пример того, как Turbo C++ автоматически
выполняет для вас конкатенацию очень длинных строк,
что позволяет получить более красивые программы.

Для расширения строковой константы за границы строки в
качестве символа продолжения можно использовать обратную
наклонную черту (\):

put(«В действительности \
это однострочная строка символов»);
Константы и их внутреннее представление

ANSI C говорит о том, что размер и численный диапазон
базовых типовданных( и различных их модификаций) зависят от
конкретной реализации компилятора и в целом от архитектуры
компьютера, на котором он установлен. Базовыми компьютерами
дляTurbo C++ являются компьютеры семействаIBM PC (и совмес-
тимые с ними), поэтому выбор внутреннего представления раз-

— 21 —
личных типов данных в целом определяется архитектурой мик-
ропроцессоров 8088 и 80×86. В следующей таблице сведены
размеры и соответствующие диапазоны значений для типов дан-
ных, определяемых в Turbo C++. Дополнительную информацию об
этих типах данных см. на стр. 39 оригинала. Внутреннее
представление типов данных см. на рис.1.

Типы данных, размеры и диапазоны значений Таблица 1.9
————————————————————
Тип Размер Диапазон Примеры применения
————————————————————
unsigned char8 0 до 255 Малые числа и полный

набор символов PC

char8 -128 до 127 Самые малые числа и
ASCII-символы

enum 16 -32,768 до 32,767 Упорядоченные наборы
значений

unsigned int 16 0 до 65,535 Большие числа и циклы

short int 16 -32,768 до 32,767 Счетчики, малые числа,
управление циклами

int 16 -32,768 до 32,767 Счетчики, малые числа,
управление циклами

unsigned long 32 0 до 4,294,967,295 Астрономические
расстояния

long 32 -2,147,483,648 до 2,147,483,647
Большие числа, население

-38 38
float 32 3.4 x 10 до 3.4 x 10
Научные расчеты (точность
7 разрядов)

-308 308
double 64 1.7 x 10 до 1.7 x 10
Научные расчеты (точность
15 разрядов)

-4932 4932
long double 80 3.4 x 10 до 1.1 x 10
Финансовые расчеты
(точность 19 знаков)

near pointer 16 Не существует Манипулирование адресами
памяти

far pointer 32 Не существует Манипулирование адресами
памяти вне текущего
сегмента
————————————————————

Страницы: 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

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

Пространство имен структур

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

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

goto s;

struct s (* // так можно; теги и имена меток находятся
в разных // адресных пространствах
int s; // так можно; теги, имена меток и имена компо-
нентов // дятся в разных адресных пространствах
float s;// так нельзя: повторение имени компонентов
структур *) s; // так можно; пространства имен переменных
различны // В С++ это допустимо только если s не имеет
// конструктора.

union s (* // так нельзя: повторение имен в пространс-
тве тегов int s; // так можно: новое пространство компонен-
тов float f;
*) f; // так можно: пространство имен переменных

struct t (*
int s; // так можно: следующее пространство имен компо-
ненто

*) s; // так нельзя: повторение имен переменных

Неполные объявления

Указатель структуры типа А допустим в объявлении другой
структуры В до объявления структуры А:

struct A;// неполное объявление struct B (* struct A
*pa *);
struct A (* struct B *pb *);

Первое объявление А называется неполным, поскольку в
этой точке отсутствует определение А. В данной ситуации не-
полное объявление допустимо, поскольку в объявлении В размер
А необязателен. Битовые поля

— 67 —
Структура можетсодержать любые комбинации битовых полей
с данными других типов.

Целочисленные компоненты типа signed или unsigned можно
объявить битовыми полями шириной от 1 до 16 бит. Ширина би-
тового поля и его опциональный идентификатор задаются следу-
ющим образом:

спецификатор-типа :ширина;

где спецификатор-типа это char, unsigned char, int или
unsigned int. Битовые поля располагаются с нижнего и кончая
саршим битом слова. Выражение «ширина» должно быть задано и
должно давать целочисленную константу со значением в диапа-
зоне от 0 до 16.

Если идентификатор битового поля опущен, то число би-
тов, заданное выражением «ширина», распределяется в памяти,
но поле при этом остается недоступным программе. Это позво-
ляет создавать битовые шаблоны для, например, аппаратных ре-
гистров компьютера, в которых некоторые биты не используют-
ся. Пример:

struct mystruct (*
int i:2;
unsigned j:5;
int :4;
int k:1;
unsigned m:4;
*) a, b, c;

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

————————————————————
\! 15\! 14\! 13\! 12\! 11\! 10\! 9 \! 8 \! 7 \! 6 \! 5
\! 4 \! 3 \! 2 \! 1 \! 0 \!
————————————————————
\! x \! x \! x \! x \! x \! x \! x \! x \! x \! x \! x

\! x \! x \! x \! x \! x \!
————————————————————
\!\!\!\!\!\!
————————————————————
\! m \! k \!не используется\! j \! i \!
————————————————————

Целочисленные поля хранятся в виде дополнения до двух,
причем крайний левый бит побещается в MSB (наиболее значащий
бит).Для битового поля типа Int (например, signed) MSB ин-
терпретируется как знаковый бит. Битовое поле шириной 2, со-
держащее двоичное 11, будет, следовательно, в случае типа
unsigned интерпретироватьсякак 3, а в случае Int как -1. В
предыдущем примере допустимое выражение a.i = 6 поместит в
a.i двоичное 10 = -2, не выдавая каких-либо предупреждений.
Поле k типа signed int шириной 1 может содержать только зна-
чения -1 и 0, так как битовый шаблон 1 будет интерпретирован
как -1.

Примечание

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

— 68 —

Выражение &mystruct.x недопустимо, так как x это иден-
тификатор битового поля, а никакой гарантии, что mystruct.x
имеет адрес на границе байта, нет.

Объединения

Объединения соответствуют типам вариантных записей язы-
ков Pascal и Modula-2.

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

union myunion (* /* тег объединения = myunion */
int i;
double d;
char ch;
*) mu, *muptr=μ

идентификатор mu типа union myunion может служить для
хранения 2-байтового значения int, 8-байтового значения
double или 1-байтового char, но одновременно — только одного
из этих значений.

Обе операции sizeof(union myunion) и sizeof (mu) возв-
ращают значение 8, но когда mu содержит объект типа int, то
6 байт остаются неиспользованными (туда помещаются симво-
лы-заполнители), а когда mu сщдержит объект типа char — то 7
байт. Доступ к компонентам объединения выполняетсяпри помощи
селекторов компонента структуры (. и ->), но требуется соб-
людать осторожность:

mu.d = 4.016;
printf(«mu.d = %f\n»,mu.d);// порядок: на дисплее mu.d
= 4.016
printf(«mu.i = %f\n»,mu.i);// забавный результат !
mu.ср = ‘A’;
printf(«mu.ch = %c\n»,mu.ch); // порядок: на дисплее
mu.ch = A
printf(«mu.d = %f\n»,mu.d); // забавный результат !
muptr->i = 3; printf(«mu.i = %d\n»,mu.i); // порядок: на
дисплее mu.i = 3

Второй оператор printf допустим, поскольку mu.i цело-
численного типа. Однако, битовая комбинация в mu.i соответс-
твует части ранее присвоенного значения типа double и не
даст как правило полезной целочисленной интерпретации.

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

Объявления объединений

Общий синтаксисобъявления объединений во многом напоми-
нает синтаксис объявления структур. Различия состоят в сле-
дующем:

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

— 69 —
2. С++ : В отличие от структур С++, объединения С++ не
могут использовать спецификаторы класса доступа:public,
private и protected. Все поля объединения имеют доступ

Страницы: 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

условное-выражение

Выражения с константами не могут содержать приводимых
ниже операций, если эти операции не содержатся в операнде
операции sizeof:

— присваивание
— декремент
— вызов функции
— запятая
Описание операций

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

Расширения C++ предлагают дополнительные операции для

— 23 —
доступа к компонентам класса и их объектам, атакже механизм
перегрузки операций. Перегрузка позволяет переопределять
действие любых стандартных операций применительно к объектам
заданного класса. В данном разделе мы ограничимся рассмотре-
нием стандартных операций TurboC++. Перегрузка рассматрива-
ется, начиная со стр.124 оригинала.

После определения стандартных операций мы обсудим типы
данных и объявления, а также объясним, как они влияют на
действие каждой операции. Затем мы перейдем к рассмотрению
синтаксиса построения выражений с помощью операций, пунктуа-
торов и объектов.

Операции в Turbo C++ определяются следующим образом:

операция: одно из

[] () . -> ++ —
& * + — тильда !
sizeof / % > < > = == != ^
\! && \!\! ?: = *=
/= %= += -= =
&= ^= \!= , # ##

Операции # и ## используются только препроцессором (см.
стр. 133 оригинала).

Следующие операции являются специфичными для C++:

:: .* ->*

За исключением операций [], () и ?:, служащих для запи-
си выражений в скобках, многосимвольные операции рассматри-
ваются в качестве одной лексемы. Лексема одной и той же опе-
рации может иметьнесколько интерпретаций, в зависимости от
контекста. Например,

A * B Умножение
*ptr Обращение по ссылке

A & B Поразрядное И
&A Операция адресации
int & Модификатор указателя (C++)

label: Метка оператора
a ? x : y Условный оператор

void func(int n); Объявление функции
a = (b+c)*d; Выражение со скобками

a, b, c; Выражение с запятой
func(a, b, c); Вызов функции

a = -b; Поразрядное вычитание (дополнение до
единицы)
-func() (*delete a;*) Деструктор (C++)

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

& Операция адресации
* Операция обращения по ссылке
+ Унарный плюс
— Унарный минус
тильда Поразрядное дополнение (дополнение до
единицы)
! Логическое отрицание

— 24 —
++ Префикс: пред- инкремент;
Постфикс: пост- инкремент
— Префикс: пред- декремент;
Постфикс: пост- декремент
Бинарные операции

Операции типа сложения + Бинарный плюс (сложение)
— Бинарный минус (вычитание)

Операции типа умножения * Умножение
/ Деление
% Остаток от деления

Операции сдвига > Сдвиг вправо

Поразрядные операции & Поразрядное И
^ Поразрядное исключающее ИЛИ
\! Поразрядное включающее ИЛИ

Логические операции && Логическое И
\!\! Логическое ИЛИ

Операторы присваивания = Присваивание
*= Присвоить произведение
/= Присвоить частное
%= Присвоить остаток
+= Присвоить сумму
-= Присвоить разность
= Присвоить сдвиг вправо
&= Присвоить поразрядное И
^= Присвоить поразрядное исключающее
ИЛИ
\!= Присвоить поразрядное ИЛИ

Операции отношения < Меньше > Больше
= Больше или равно

Операции равенства == Равно
!= Не равно

Операции выбора . Прямой селектор компонента
компонента -> Косвенный селектор компонента

Операции с компонентами :: Доступ/разрешение контекста
класса .* Обращение через указатель
к компоненту класса
->* Обращение через указатель
к компоненту класса

Условные операции a ? x : y «Если a то x иначе y»

Операция запятой , Вычислить, например, a, b, c
слева — направо

Функции этих операций,также как их синтаксис, приоритет
и свойства ассоциативности рассматриваются, начиная со стр.
73 оригинала.

Пунктуаторы

В TurboC++ пунктуаторы, также называемые разделителями,
определяются следующим образом:

— 25 —
пунктуатор: одно из
[ ] ( ) (* *) , ; : … * = #

Квадратные скобки

[] (открывающая и закрывающая квадратные скобки) указы-
вают на индексы одно- и многомерных массивов:

char ch, str[] = «Stan»
int mat[3][4]; /* матрица 3 x 4 */
ch = str[3]; /* 4-й элемент */

Круглые скобки

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

d = c * (a + b); /* переопределение нормального приори-
тета */
/* выполнения операций */
if (d == z) ++x; /* важно при использовании условных
операций */
func(); /* вызов функции без аргументов */
int (*fptr)(); /* объявление указателя функции */
fptr = func; /* отсутствие () означает указатель функ-
ции */
void func2(int n); /* объявление функции с аргументами */

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

#define CUBE(x) ((x) * (x) * (x))

Использование круглых скобок для изменения нормальных
приоритетов операцийи правил ассоциативности см. на стр.76
оригинала.

Страницы: 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

private.

3. Объединения инициализируются через компонент, объяв-
ленный первым

union local87 (*
int i;
double d;
*) a = (* 20*);

4. С++ : Объединение не может участвовать в иерархии
класса. Оно не может являться производным от какого-либо
класса или быть базовым классом. Объединение может иметь
конструктор.

5. С++ : Анонимные объединения не могут иметь компонен-
ты-функции.
Перечислимые данные

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

enum days (* sun, mon, tues, wed, thur, fri, sat *)
anyday;

устанавливает уникальный интегральный тип, enum days,
переменную anyday этого типа и набор нумераторов
(sun,mon,…), которым соответствуют целочисленные констан-
ты.

Turbo C++ может хранить нумераторы в одном байте, если
это позволяет диапазон значений нумераторов, когда выключена
опция -b (по умолчанию она включена; это означает, что дан-
ные типа enum всегда int), но при использовании их в выраже-
ниях выполняется этих данных преобразования к типу int.
Идентификаторы, используемые в списке нумераторов, неявно
получают тип unsigned char или int, в зависимости от значе-
ний нумераторов. Если все значения могут быть представлены
типом unsigned char, то это и будет типом каждого нумерато-
ра.

C++ В С переменной перечислимого типа может быть прис-
воено любое значение типа int — кроме этого, никакого конт-
роля типа не выполняется. В С++ переменной перечислимого
типа может присваиваться только значение одного из ее нуме-
раторов. Таким образом,

anyday = mon; // так можно
anyday = 1; // так нельзя, даже хотя mon == 1

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

enum days payday, holiday; // объявление двух переменных

С++ В С++ ключевое слово enum можно опустить, если в
пределах данного контекста имя days не дублируется.

Как и в случае объявлений struct и union, если далее
переменные данного типа enum не требуются, тег может быть
опущен:

— 70 —
enum (* sun, mon, tues, wed, thur, fri, sat *) anyday;
/* анонимный тип enum */

Подробное описание констант перечислимого типа см. на
стр. 17 оригинала.

Нумераторы, перечисленные внутри фигурных скобок, назы-
ваются перечислимыми константами. Каждой из них назначается
фиксированное целочисленное значение. При отсутствии явно
заданных инициализаторов первый нумератор (sun) устанавлива-
ется в ноль, а каждый последующий нумератор имеет значение
на единицу больше, чем предыдущий (mon = 1, tue = 2 и т.д.).

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

/* выражение инициализатора может включать в себя нуме-
раторы, объявленные ранее */
enum coins (* penny = 1, tuppence, nickel = penny + 4,
dime =10, quarter = nickel * nickel *) smallchange;

tuppence примет значение 2, nickel — значение 5, а
quarter — значение 25.

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

не запрещено.

Тип enum может участвовать во всех конструкциях,допус-
кающих использование типов int.

enum days (* sun, mon, tues, wed, thur, fri, sat *) anyday;
enum days payday;
typedef enum days DAYS;
DAYS *daysptr;
int i = tues;
anyday = mon; // так можно
*daysptr = anyday; // так можно
mon = tues; // неверно: mon — это константа

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

int mon = 11;
(*
enum days (* sun, mon, tues, wed, thur, fri, sat *) anyday;
/* нумератор mon скрывает внешнее объявление int mon */
struct days (* int i, j;); // неверно: дублируется тег days
double sat; // неверно: переопределение sat
*)
mon = 12; // снова в контексте int mon

C++ В С++ нумераторы, объявленные в пределах клас-
са,имеют контекст этого класса.

Выражения

В таблице 1.19 показано, каким образом комбинируются
идентификаторы и операции для составления грамматически вер-
ных «фраз».

— 71 —
Выражением называется последовательность операций, опе-
рандов и пунктуаторов, задающих определенное вычисление.
Формальный синтаксис, показанный в таблице 1.19, обозначает,
что выражения определяются рекурсивно: под-выражения могут
быть вложены без формальных ограничений. (Однако, если ком-
пилятор не сможет обработать какое-либо слишком сложное вы-
ражение, то будет выдано сообщение об ошибке).

Выражения Turbo C++ Таблица 1.19
————————————————————
первичное-выражение:
литерал
псевдо-переменная
(выражение)
this (только С++)
:: идентификатор (только С++)
:: имя-функции-операции (только С++)
имя

литерал:
целочисленная-константа
символьная-константа
константа-с-плавающей-точкой
строка

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

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

постфиксное-выражение:
первичное-выражение
постфиксное-выражение[выражение]
постфиксное-выражение ()
постфиксное-выражение () (только С++)
постфиксное-выражение . имя постфиксное-выражение -> имя
постфиксное-выражение ++ постфиксное-выражение —

список-выражений:
выражение-присваивания
список-выражений , выражение-присваивания

унарное-выражение:
постфиксное-выражение
++ унарное-выражение
— унарное-выражение
унарная-операция выражение-приведения
sizeof унарное-выражение
sizeof (имя-типа)
выражение-распределения (только С++)
выражение-отмены-распределения (только С++)

унарная-операция: одно из
& * + — тильда !

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

Страницы: 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