2.4  Константы

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

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

Десятичные константы строятся из цифр десятичной системы счисления (0 – 9) с диапазоном изменения от 0 до 4 294 967 295. Константы, выходящие за указанные пределы, вызывают ошибку. Десятичные константы не могут начинаться с нулей. Целочисленная константа с ведущим нулем рассматривается как восьмеричная. Например:

int i = 10;   /* десятичная */

int i = 010;  /* восьмеричная */

int i = 0;    /* десятичная или восьмеричная?*/

Отрицательные константы – это десятичные константы без знака, к которым применена унарная операция «минус».

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

Шестнадцатеричные константы строятся из цифр шестнадцатеричной системы счисления (0 – 9, A,B,C,D,E,F, или a,b,c,d,e,f) и должны начинаться с 0x (или 0X). Шестнадцатеричные константы, превышающие 0xFFFFFFFF, приводят к ошибке.

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

Суффиксы можно указывать для одной и той же константы в произвольном порядке и набирать в любом регистре, например: ul, lu, UL и т.д. Если константа имеет оба суффикса u и l (ul, lu, Ul, lU, uL, Lu, LU или UL), то она будет иметь тип данных unsigned long int.

Константа с плавающей точкой может иметь следующие компоненты:

· десятичное целое;

· десятичную точку;

· десятичное дробное;

· e или E и целочисленную экспоненту со знаком;

· суффиксы типа f, F, l или L

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

Отрицательные константы с плавающей точкой записываются как положительные константы с префиксом унарной операцией «минус»(–). Примеры констант с плавающей точкой:

23.45e6  23.45 × 106;

1.  1.0 × 100;

– 1.23   – 1.23;

2e – 5  2.0 × 10 – 5,

3E+10     3.0 × 1010;

.09E34   0.09 × 1034.

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

Символьная константа – это один или более символов, заключенных в одинарные кавычки. В языке С++ односимвольная константа имеет тип char.  Многосимвольные константы как в языке C, так и в языке C++, имеют тип данных int .

Символьная константа, которой предшествует суффикс L, называется длинной символьной константой и имеет тип данных wchar_t (интегральный тип, определяемый в подключаемом файле stddef.h). Например: x = L ‘A’. Длинные символьные константы предназначены для такого набора символов, где значение символа не помещается в один байт.

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

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

В примере

enum color { red, yellow, green }; // красный  желтый  зеленый

red, yellow и green  –  это перечислимые константы типа color, которые могут быть назначены любым переменным типа color или любой другой переменной целочисленного типа. Значения, принимаемые перечислимыми константами, равны:

red = 0,  yellow = 1, green = 2

при условии отсутствия явных инициализаторов (по умолчанию). В следующем примере:

enum color { red, yellow=3, green=red+1 };

константы имеют следующие значения:

red = 0,  yellow = 3,  green = 1.

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

enum color { red, yellow=1, green=yellow – 1 };

где red = 0,  yellow = 1,  green = 0.

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

Используя ключевое слово const, можно определить переменную для хранения значения константы:

const int MaxLines = 100;

Примечание: Объект типа const иногда называют именованной константой, а не переменной типа константа, так как употребление термина «переменная» в данном случае неправомерно.

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

const double CD = 2.5;

double D;

D = CD; // для чтения константы

CD = 5.0; // ОШИБКА: нельзя присвоить новое значение константе

++CD;// ОШИБКА: нельзя изменить значение типа const

Константную переменную можно инициализировать, используя как константное выражение (например, 5), так и другую переменную. Например, все приведенные далее определения константных переменных являются корректными (первые два инициализируют константу с константными выражениями, а вторые два – с другими переменными):

void Func (int Parm)

{

int L = 3;

constint CI1 = 5;

constint CI2 = 2 * sizeof (float);

constint CI3 = L;

constint CI4 = Parm;

}

Если константная переменная инициализирована выражением, содержащим другие переменные, то ее нельзя использовать для определения размерности массива (этот метод может оказаться некорректным для динамически создаваемого массива, размер которого определяется во время выполнения). Например:

void Func (int Parm)

{

const int CI1 = 100;

const int CI2 = Parm;

char Bufl [СI1];// правильно

char Buf2 [CI2];// ОШИБКА: требуется константное выражение

}

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

Примечание: Константная переменная имеет преимущества перед константой, определенной оператором #define, так как к ней можно обратиться с помощью символического отладчика.