Каким образом в программе С++ определяется тип литерала?

Представление литералов в программном коде существенно зависит от типа, к которому относится литерал. Так, отдельные символы – литералы типа char указываются в одинарных кавычках, например ‘a’ или ‘d’. Для литералов типа wchar_t (напомним, это расширенный 16-битовый символьный тип) перед непосредственно значением указывается префикс L. Примеры литералов типа wchar_t: L’a’, L’A’, L’d’ и L’D’.

Несмотря на то, что в C++ нет отдельного типа для строчных (текстовых) переменных, в C++ существуют литералы типа текстовой строки. Соответствующие значения указываются в двойных кавычках. Примером текстового литерала, например, может быть фраза «Hello, World!».

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

Тем не менее, в некоторых случаях необходимо в явном виде указать принадлежность литерала к определенному типу. Обычно это делают с помощью специальных суффиксов. Суффикс F после числа в формате с плавающей точкой означает принадлежность литерала к типу float (например, 5.3F). Чтобы литерал относился к типу long double, используют суффикс L (например, 5.3L). Этот же суффикс, но у целочисленного литерала означает принадлежность последнего к типу long int (например, 123L). Суффикс U используется с целочисленными литералами для отнесения их к типу unsigned int (например, 123U).

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

В C++ восьмеричные литералы вводятся с помощью арабских цифр, но каждый восьмеричный литерал должен начинаться с нуля. Поэтому хотя с математической точки зрения первый нуль и является незначащим, в C++ литералы 10 и 010 не эквиваленты. Первый является десятичным значением 10, в то время как второй литерал – восьмеричный и в десятичной системе счисления соответствует числу 8. Шестнадцатеричные литералы начинаются с последовательности 0x или 0X. Примеры шестнадцатеричных литералов: 0x10 (десятичное число 16), 0X309 (десятичное число 777), 0x1FA (десятичное число 506).

В С++ имеется набор встроенных типов данных для представления целых и вещественных чисел, символов, а также тип данных “символьный массив”, который служит для хранения символьных строк. Тип char служит для хранения отдельных символов и небольших целых чисел. Он занимает один машинный байт. Типы short, int и long предназначены для представления целых чисел. Эти типы различаются только диапазоном значений, которые могут принимать числа, а конкретные размеры перечисленных типов зависят от реализации. Обычно short занимает половину машинного слова, int – одно слово, long – одно или два слова. В 32-битных системах int и long, как правило, одного размера.

Типы float, double и long double предназначены для чисел с плавающей точкой и различаются точностью представления (количеством значащих разрядов) и диапазоном. Обычно float (одинарная точность) занимает одно машинное слово, double (двойная точность) – два, а long double (расширенная точность) – три.

char, short, int и long вместе составляют целые типы, которые, в свою очередь, могут быть знаковыми (signed) и беззнаковыми (unsigned). В знаковых типах самый левый бит служит для хранения знака (0 – плюс, 1 – минус), а оставшиеся биты содержат значение. В беззнаковых типах все биты используются для значения. 8-битовый тип signed char может представлять значения от -128 до 127, а unsigned char – от 0 до 255.

***

Когда в программе встречается некоторое число, например 1, то это число называется литералом, или литеральной константой. Константой, потому что мы не можем изменить его значение, и литералом, потому что его значение фигурирует в тексте программы. Литерал является неадресуемой величиной: хотя реально он, конечно, хранится в памяти машины, нет никакого способа узнать его адрес. Каждый литерал имеет определенный тип. Так, 0 имеет тип int, 3.14159 – тип double.

Литералы целых типов можно записать в десятичном, восьмеричном и шестнадцатеричном виде. Вот как выглядит число 20, представленное десятичным, восьмеричным и шестнадцатеричным литералами:

20 // десятичный
024 // восьмеричный
0х14 // шестнадцатеричный

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

По умолчанию все целые литералы имеют тип signed int. Можно явно определить целый литерал как имеющий тип long, приписав в конце числа букву L (используется как прописная L, так и строчная l, однако для удобства чтения не следует употреблять строчную: ее легко перепутать с

1). Буква U (или u) в конце определяет литерал как unsigned int, а две буквы – UL или LU – как тип unsigned long. Например:

128u 1024UL 1L 8Lu

Литералы, представляющие действительные числа, могут быть записаны как с десятичной точкой, так и в научной (экспоненциальной) нотации. По умолчанию они имеют тип double. Для явного указания типа float нужно использовать суффикс F или f, а для long doubleL или l, но только в случае записи с десятичной точкой. Например:

3.14159F 0/1f 12.345L 0.0
3el 1.0E-3E 2. 1.0L

Слова true и false являются литералами типа bool.

Представимые литеральные символьные константы записываются как символы в одинарных кавычках. Например:

‘a’ ‘2’ ‘,’ ‘ ‘ (пробел)

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

новая строка \n
горизонтальная табуляция \t
забой \b
вертикальная табуляция \v
возврат каретки \r
прогон листа \f
звонок \a
обратная косая черта \\
вопрос \?
одиночная кавычка \’
двойная кавычка \»

escape-последовательность общего вида имеет форму \ooo, где ooo – от одной до трех восьмеричных цифр. Это число является кодом символа. Используя ASCII-код, мы можем написать следующие литералы:

\7 (звонок) \14 (новая строка)
\0 (null) \062 (‘2’)

Символьный литерал может иметь префикс L (например, L’a’), что означает специальный тип wchar_t – двухбайтовый символьный тип, который применяется для хранения символов национальных алфавитов, если они не могут быть представлены обычным типом char, как, например, китайские или японские буквы.

Строковый литерал – строка символов, заключенная в двойные кавычки. Такой литерал может занимать и несколько строк, в этом случае в конце строки ставится обратная косая черта. Специальные символы могут быть представлены своими escape-последовательностями. Вот примеры строковых литералов:

«» (пустая строка)
«a»
«\nCC\toptions\tfile.[cC]\n»
«a multi-line \
string literal signals its \
continuation with a backslash»

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

Литерал ‘A’ задает единственный символ А, а строковый литерал «А» – массив из двух элементов: ‘А’ и \0 (пустого символа).

Раз существует тип wchar_t, существуют и литералы этого типа, обозначаемые, как и в случае с отдельными символами, префиксом L:

L»a wide string literal»

Строковый литерал типа wchar_t – это массив символов того же типа, завершенный нулем.

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

«two» «some»

породит массив из восьми символов – twosome и завершающий нулевой символ. Результат конкатенации строк разного типа не определен. Если написать:

// this is not a good idea
«two» L»some»

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

***
Источники:

*https://codernet.ru/books/c_plus/samouchitel_c_s_primerami_i_zadachami_aleksandr_vasilev/

*http://mycpp.ru/cpp/book/c03_1.html

*https://ppt-online.org/418330

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *