PVOID - Константы

Этот раздел является переводом туториала C++ Language


   Константы - это выражения с фиксированным значением.

Литералы


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

a = 5;

Число 5 в этом фрагменте кода являлось литеральной константой.

   Литеральные константы могут быть разделены на: целочисленные, с плавающей точкой, символьные, строковые, Булевы, указатели и литералы, определяемые пользователем.

Целые числа


1776
707
-273

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

   В дополнение к десятичным числам (тем, которые большинство из нас используют каждый день), C++ позволяет использовать восьмеричные (основание 8) и шестнадцатеричные числа (основание 16) как литеральные константы. Для восьмеричных литералов, цифрам предшествует символ 0 (ноль). Шестнадцатеричным литералам предшествуют символы 0x (ноль, x). Например, следующие литеральные константы эквивалентны: 

75         // десятеричная
0113       // восьмеричная
0x4b       // шестнадцатеричная

   Все они представляют собой одно и то же число: 75 (семьдесят пять), выраженное как десятичное, восьмеричное и шестнадцатеричное число, соответственно. 

   Эти литеральные константы имеют тип, так же как переменные. По умолчанию, целочисленные литералы типа int. Тем не менее, определенные суффиксы могут дополнять целочисленный литерал для указания другого целого типа:

 Суффикс   Модификатор типа 
 u или U  unsigned
 l или L  long
 ll или LL  long long

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

 Например:

75         // int
75u        // unsigned int
75l        // long
75ul       // unsigned long 
75lu       // unsigned long

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

 

Числа с плавающей точкой


   Они выражают действительные значения с помощью десятичных чисел и/или экспоненты. Они могут включать десятичную точку, символ e (который выражает "десять в степени X", где X это целое значение, которое следует за символом e), а также десятичную точку и символ e вместе:

3.14159    // 3.14159
6.02e23    // 6.02 x 10^23
1.6e-19    // 1.6 x 10^-19
3.0        // 3.0  

   Это четыре корректных десятичных числа, выраженные на C++. Первое число - это число PI, второе - число Авогадро, третье - заряд электрона (крайне маленькое число) - все они указаны приближенно, и последнее - число три, выраженное как числовой литерал с плавающей точкой.

   По умолчанию литералам с плавающей точкой соответствует тип double. Литералы с плавающей точкой типа float или long double могут быть определены путем добавления одного из следующих суффиксов:

 Суффикс   Тип
 f или F  float 
 l или L  long double 

 Например:

3.14159L   // long double
6.02e23f   // float 

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

 

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


   Символьные и строковые литералы заключаются в кавычки:

'z'
'p'
"Hello world"
"How do you do?"

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

   Как символьные, так и строковые литералы должны быть заключены в кавычки, чтобы отличать их от возможных идентификаторов переменных или зарезервированных слов. Обратите внимание на разницу между этими двумя выражениями:

 x

 'x'

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

  Символьные и строковые литералы могут также представлять специальные символы, которые трудно или невозможно выразить иначе в исходном коде программы, такие как символ новой строки (\n) или табуляции (\t). Эти специальные символы всегда экранизируются символом обратного слэша (\).

 Здесь приведен список управляющих символов:

 Управляющий символ  Описание
 \n  новая строка 
 \r  возврат каретки 
 \t  табуляция
 \v  вертикальная табуляция
 \b  возврат на одну позицию 
 \f  прогон страницы
 \a  звуковой сигнал
 \'  одинарная кавычка (')
 \"  двойная кавычка (")
 \?  вопросительный знак (?)
 \\  обратный слэш (\)

   Например:

 '\n'

 '\t'

 "Left \t Right"

 "one\ntwo\nthree"

   Компьютеры представляют символы как числовые коды: как правило, они используют расширение системы кодирования символов ASCII (смотрите ASCII code для получения дополнительной информации). Символы также могут быть представлены в литералах с использованием числового кода путем написания обратного слэша (\), за которым следует код, выраженный  восьмеричным или шестнадцатеричным числом. Для восьмеричного значения цифры следуют непосредственно за обратным слэшем; для использования шестнадцатеричного значения необходимо поместить символ x между обратным слэшем и цифрами, например: \x20 или \x4A.

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

"this forms" "a single"     " string "
"of characters"

   Это строковый литерал, эквивалентный:

"this formsa single string of characters"

   Обратите внимание на то, что пробелы внутри кавычек являются частью литерала, в то время как те, что вне кавычек - нет.

   Некоторые программисты также используют трюк для включения длинных строковых литералов в несколько строк: в C++ обратный слэш (\) в конце строки считается символом продолжения строки, который объединяет текущую строку со следующей в одну строку. Поэтому следующий код:

x = "string expressed in \
two lines"

 эквивалентен:

x = "string expressed in two lines"

   Все символьные и строковые литералы, описанные выше, состоят из символов типа char. Другой тип символов можно определить путем использования одного из следующих префиксов:

 Префикс   Тип символов 
 u  char16_t
 U  char32_t
 L  wchar_t

   Обратите внимание, что в отличие от суффиксов типа для целочисленных литералов, эти префиксы чувствительны к регистру: нижний регистр для char16_t и верхний для char32_t и wchar_t.

 Помимо указанных префиксов u, U и L, для строковых литералов существуют еще два дополнительных префикса:

 Префикс   Описание 
 u8  Строковый литерал кодируется в UTF-8 в исполняемом файле 
 R  Строковый литерал является сырой строкой (raw string)

   В сырых строках обратные слэши, а также одинарные и двойные кавычки являются допустимыми символами; содержимое литерала находится между начальными символами R"sequence( и конечыми )sequence", где sequence - это любая последовательность символов (включая пустую последовательность). Содержимое строки - это то, что находится внутри скобок, а сама разделяющая последовательность игнорируется. Например:

R"(string with \backslash)"
R"&%$(string with \backslash)&%$"

   Обе строки выше эквивалентны строке "string with \\backslash". Префикс R может быть объединен с любым другим префиксом, таким как u, L или u8.

 

 Другие литералы


   В C++ существует три ключевых слова, являющихся литералами: true, false и nullptr:

  • true и false - это два возможных значения для переменной типа bool.
  • nullptr - это значение пустого указателя.
bool foo = true;
bool bar = false;
int* p = nullptr;

 

Типизированные константные выражения


   Иногда бывает удобно дать имя константному значению:

const double pi = 3.1415926;
const char tab = '\t';

   Эти имена затем можно использовать вместо литералов, которыми они были определены:

#include <iostream>
using namespace std;

const double pi = 3.14159;
const char newline = '\n';

int main ()
{
  double r=5.0;               // радиус
  double circle;

  circle = 2 * pi * r;
  cout << circle;
  cout << newline;
}
31.4159

 

 Определения препроцессора (#define)


   Другой механизм для именования констант - это использование определений препроцессора. Они имеют следующую форму:

 #define identifier replacement 

   После этой директивы любое вхождение identifier в коде интерпретируется как replacement, где replacement - это любая последовательность символов (до конца строки). Эта замена производится препроцессором и происходит перед компиляцией, вызывая своего рода слепую замену: корректность типов или синтаксиса не проверяется каким-либо образом. 

Например:

#include <iostream>
using namespace std;

#define PI 3.14159
#define NEWLINE '\n'

int main ()
{
  double r=5.0;               // радиус
  double circle;

  circle = 2 * PI * r;
  cout << circle;
  cout << NEWLINE;
}
31.4159


   Обратите внимание, что строки #define - это директивы препроцессора и являются однострочными инструкциями, которые в отличие от выражений C++ не требует точки с запятой (;) в конце; директива продлевается автоматически до конца строки. Если в строке присутствует точка с запятой, то она считается частью, заменяющей последовательности, и также включается при каждом случае замены.