Разное

C литералы: C# и .NET | Литералы

Содержание

C#. Литералы. Примеры литералов | BestProg


Содержание


Поиск на других ресурсах:

1. Что такое литералы в языке C#? Примеры литералов.

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

Примеры литералов:

250 - целочисленный литерал типа int
's' - литерал символьного типа char
'@' - литерал символьного типа char
11.235 - литерал с плавающей запятой типа double
"Text" - литерал строчного типа string

  ⇑


2. Какого типа могут быть литералы?

Литералы могут быть любого простого типа. Представление любого литерала зависит от конкретного типа.

В зависимости от значения литералы могут быть:

  • целочисленных типов — int, uint, long, ulong;
  • типов с плавающей точкой — float, double, decimal ;
  • символьного типа char;
  • строчного типа string.

  ⇑


3. Как представляются целочисленные литералы?

По умолчанию, все целочисленные литералы имеют тип int:

Примеры литералов типа int:

28
39982
-990

Для того чтобы литерал имел тип long к нему нужно добавить суффикс ‘l‘ или ‘L‘. Примеры литералов типа long:

28L
39982l
-30l

Для того чтобы литерал имел беззнаковый целочисленный тип к нему нужно добавить суффикс ‘u‘ или ‘U‘. Примеры литералов типа uint:

28u
0U
1500U

Примеры литералов типа ulong:

200u
1234567UL
45600009uL

  ⇑


4. Можно ли целочисленные литералы присваивать переменным типа byte, sbyte, short и ushort?

Можно, но при условии, что присваиваемое значение может быть представлено целочисленным типом.

Пример:

byte b;
sbyte sb;
short s;
ushort us;

b = 20;
sb = 30;
s = -30;
us = 100;

// Ошибка переполнения: "Constant value cannot be converted to 'sbyte'"
// sb = 130;

  ⇑


5. Каким образом представляются литералы, принадлежащие к типам с плавающей запятой?

По умолчанию, литералы типа с плавающей запятой относятся к типу double. Кроме того, к литералам типа double можно прибавлять суффикс ‘d‘ или ‘D‘ (это ничего не меняет).

Примеры литералов типа double:

278.39904
-42000.4
-42000.4D
0.0d
1E6
5.6e-3

Если нужно, чтобы литерал имел тип float, к нему нужно добавить суффикс ‘f‘ или ‘F‘. Примеры литералов типа float:

28.5f
28.5F
-600.321235F

Если нужно, чтобы литерал имел тип decimal, то к нему прибавляется суффикс ‘m‘ или ‘M‘. Примеры литералов типа decimal:

2084797985789.88m
-9.3886M
3049595882M

  ⇑


6. Как осуществляется присвоение значения литералов переменным типов float и decimal?

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

float f;
double d;
decimal x;

f = -600.321235F;
d = 1e9; // d = 1000000000
d = -2.2E-5; // d = -0.000022
x = 3049595882M;

  ⇑


7. Как представляются значения целочисленных литералов в шестнадцатеричной системе исчисления?

Язык C# разрешает также представлять целочисленные литералы в шестнадцатеричной системе исчисления. Шестнадцатеричные литералы должны начинаться с символов «0x«.

В этих литералах используются числа от 0 до 9, а также буквы от ‘А‘ к ‘F‘.



Примеры представления литералов в шестнадцатеричной системе исчисления:

0xFFFF
0x10
0xaddf8
0Xaddf8
0XE

  ⇑


8. Как представляются символьные литералы (char)?

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

Примеры символьных литералов:

'A'
'#'
'-'

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

Примеры управляющих последовательностей символов:

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

Пример использования в программе управляющих последовательностей:

char symbol;
symbol = '\t'; // горизонтальная табуляция
symbol = '\\'; // обратная косая черта

  ⇑


9. Как представляются строчные литералы?

В языке C# строчный литерал представляет собой набор символов, взятых в двойные кавычки. Примеры строчных литералов

"Это строчный литерал"
"This is a text"
"1234567890"
"First\n\tSecond\n\tThird\n\t"
""

Если нужно задать в виде литерала следующий путь:

C:\Programs\myfile.txt

то он будет иметь такой вид:

"C:\\Programs\\myfile.txt"

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

string path = "c:\\programs\\c_sharp\\myfile.txt";

  ⇑


10. Какой вид имеет буквальный строчный литерал?

Буквальный строчный литерал начинается с символа @ после которого следует строка в кавычках. Содержимое буквального строчного литерала принимается без изменений и может быть расширено до двух и более строк.

Например:

string str = @"Буквальный
строчный
литерал";

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

  ⇑


Связанные темы

  ⇑


Пользовательские литералы в C ++

U Ser D efined L iterals (UDL) добавляют в C ++ от C ++ 11. Хотя C ++ предоставляет литералы для различных встроенных типов, но они ограничены.

Примеры литералов для встроенных типов:

// Examples of classical literals for built-in types.
42    // int
2.4    // double
3.2F    // float
'w'    // char
32ULL    // Unsigned long long
0xD0    // Hexadecimal unsigned
"cd"    // C-style string(const char[3]")

Почему мы используем UDL?
Давайте рассмотрим приведенный ниже пример, чтобы понять необходимость UDL.

long double Weight = 2.3; //  pounds? kilograms? grams?

// With UDL, we attach units to the values which has
// following advantages
// 1) The code becomes readable.
// 2) Conversion computations are done at compile time. 
weight = 2.3kg;
ratio = 2.3kg/1.2lb;

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

Примеры пользовательских литералов:

"hello"s            // string
4.3i                // imaginary
101000111101001b    // binary
53h                // hours
234093270497230409328432840923849 // extended-precision

UDL обрабатываются как вызов литерального оператора. Поддерживается только суффиксная форма. Имя литерального оператора — оператор «», за которым следует суффикс.

Пример 1:

#include<iostream>
#include<iomanip>

using namespace std;

  

  

long double operator"" _kg( long double x )

{

    return x*1000;

}

  

long double operator"" _g( long double x )

{

    return x;

}

  

long double operator"" _mg( long double x )

{

    return x / 1000;

}

  

int main()

{

    long double weight = 3.6_kg;

    cout << weight << endl;

    cout << setprecision(8) << ( weight + 2.3_mg ) << endl;

    cout << ( 32.3_kg / 2.0_g ) << endl;

    cout << ( 32.3_mg *2.0_g ) << endl;

    return 0;

}

Выход:

3600
3600.0023
16150
0.0646

Пример 2:

#include <iostream>
#include <complex>

using namespace std;

  

constexpr complex <double> operator"" _i( long double d )

{

    return complex <double> { 0.0 , static_cast <double> ( d ) };

}

  

int main()

{

    complex <double> z = 3.0 + 4.0_i;

    complex <double> y = 2.3 + 5.0_i;

    cout << "z + y = " << z+y << endl;

    cout << "z * y = " << z*y << endl;

    cout << "abs(z) = " << abs(z) << endl;

    return 0;

}

Выход:

z + y = (5.3,9)
z * y = (-13.1,24.2)
abs(z) = 5

Здесь constexpr используется для оценки времени компиляции.

Ограничение:
UDL может работать только со следующими параметрами:

char const*
unsigned long long
long double
char const*, std::size_t
wchar_t const*, std::size_t
char16_t const*, std::size_t
char32_t const*, std::size_t

Но возвращаемое значение может быть любого типа.

Эта статья предоставлена Махимой Варшней . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи [email protected]. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

Рекомендуемые посты:

Пользовательские литералы в C ++

0.00 (0%) 0 votes

C Language — Строковые литералы

пример

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

const char *get_hello() {
    return "Hello, World!";  /* safe */
}

По историческим причинам элементы массива, соответствующие строковому литералу, формально не const . Тем не менее, любая попытка изменить их имеет неопределенное поведение . Как правило, программа, которая пытается изменить массив, соответствующий строковому литералу, выйдет из строя или иным образом неисправна.

char *foo = "hello";
foo[0] = 'y';  /* Undefined behavior - BAD! */

Если указатель указывает на строковый литерал — или где он иногда может это сделать — желательно объявить референта const указателя, чтобы избежать случайного использования такого неопределенного поведения.

const char *foo = "hello";
/* GOOD: can't modify the string pointed to by foo */

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

char *foo = "hello";
foo = "World!"; /* OK - we're just changing what foo points to */

Более того, хотя инициализаторы для массивов char могут иметь ту же форму, что и строковые литералы, использование такого инициализатора не связывает характеристики строкового литерала с инициализированным массивом. Инициализатор просто обозначает длину и начальное содержимое массива. В частности, элементы могут быть изменены, если явно не объявлены const :

char foo[] = "hello";
foo[0] = 'y';  /* OK! */

C++ — Целочисленный литерал | c++ Tutorial

пример

Целочисленный литерал является основным выражением формы

  • десятичный литерал

Это отличная от нуля цифра (1, 2, 3, 4, 5, 6, 7, 8, 9), за которой следует ноль или более десятичных цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

int d = 42;

  • восьмеричный литерал

Это цифра нуль (0), за которой следует ноль или более восьмеричные цифры (0, 1, 2, 3, 4, 5, 6, 7)

int o = 052

  • шестигранный буквальный

Это последовательность символов 0x или последовательность символов 0X, за которой следует одна или несколько шестнадцатеричных цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C , d, D, e, E, f, F)

int x = 0x2a; int X = 0X2A;

  • бинарный-литерал (с C ++ 14)

Это последовательность символов 0b или последовательность символов 0B, за которой следует одна или несколько двоичных цифр (0, 1)

int b = 0b101010; // C++14

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

  • unsigned-suffix (символ u или символ U)

unsigned int u_1 = 42u;

  • long-suffix (символ l или символ L) или длинный-длинный суффикс (последовательность символов ll или последовательность символов LL) (поскольку C ++ 11)

Следующие переменные также инициализируются с тем же значением:

unsigned long long l1 = 18446744073709550592ull; // C++11
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14

Заметки

Буквы в целочисленных литералах не чувствительны к регистру: 0xDeAdBaBeU и 0XdeadBABEu представляют одинаковое число (одним исключением является длинный-длинный суффикс, который является либо ll, либо LL, ни lL, ни Ll)

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

В C до C99 (но не в C ++) недопустимые десятичные значения, не соответствующие длинному int, имеют тип unsigned long int.

При использовании в контрольном выражении #if или #elif все подписанные целочисленные константы действуют так, как будто они имеют тип std :: intmax_t, и все неподписанные целочисленные константы действуют так, как будто они имеют тип std :: uintmax_t.

Литерал (информатика) — это… Что такое Литерал (информатика)?

У этого термина существуют и другие значения, см. Литерал.

Литерал (англ. literal — константа) — запись в исходном коде компьютерной программы, представляющая собой фиксированное значение[1].

Описание

Литералы представляют собой константы, непосредственно включаемые в текст программы в отличие от прочих данных — констант и переменных, обращение к которым осуществляется посредством ссылок[1]. Литералы не могут быть изменены в тексте программы.

В следующем примере 1 и Кот это литералы, а a1, c и cat — переменные:

int a1=1;
int c=a1;
string cat="Кот";

Литерал в языке Python — это выражение, создающее объект.

Типы литералов

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

Обычно выделяют следующие элементарные типы литералов:

Числовые литералы — литералы, для записи чисел. Иногда, числовые литералы детализируются целые литералы, дробные литералы, с различной точностью представления и записанные в различной системе счисления (например, битовые литералы в PL/I). Обычно, в программах числовые литералы записываются непосредственно числом. В следующем примере 100 и 3.1415 — числовые литералы:

int a=100;
float b=3.1415;

Строковые литералы, обычно, представляют собой строку символов, заключённую в кавычки или скобки. Иногда выделяют, также, символьные литералы, включающие один символ. В разных языках программирования допускаются различные типы кавычек. Например, в следующем примере на языке JavaScript один и два — строковые литералы записанные с использованием различных допустимых типов кавычек:

var one="один";
var two='два';

Логические литералы, Логические значения — два литерала: true и false или их аналоги — T, t, Y, y, F, f, N, n, NIL и т. п.. Например:

bool t=true;
bool f=false;

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

Null-литерал, Пустое значение — особый тип литерала, в зависимости от языка программирования, относящийся к ссылочному либо объектному типу. Единственное допустимое значение этого типа литералов null, или аналог, например NIL, None, Nothing — ссылка никуда не ведёт либо объект отсутствует.

T o=null;

Регулярные выражения. В некоторых языках программирования регулярные выражения представляют собой литерал особого типа для поиска по шаблону[2]. Например:

/javascript/gi 

В некоторых объектно ориентированных языках программирования (например, ECMAScript v3) допускается использовать выражения, которые служат массивами-литералами и объектами-литералами[2]. Например:

[1,2,3,4,5] // Инициализатор массива
{x:1, y:2} // Инициализатор объекта

Иногда анонимные функции относят к литералам-функциям, а анонимные объекты к литералам-объектам.

Примечания

  1. 1 2 Статья literal в Энциклопедии PC Magazine
  2. 1 2 Флэнаган Д. JavaScript. Подробное руководство. — Пер. с англ. — СПб: Символ-Плюс, 2008. — 992 с., ил.

Ссылки

Пользовательские литералы (начиная с C ++ 11) — cppreference.com

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

[править] Синтаксис

Определенный пользователем литерал — это выражение любой из следующих форм

десятично-буквальный суффикс ud (1)
восьмеричный буквенный суффикс ud (2)
буквальный шестнадцатеричный суффикс ud (3)
двоично-буквальный суффикс ud (4)
дробно-постоянная экспонента-часть (необязательно) ud-суффикс (5)
порядковая часть последовательности цифр суффикс ud (6)
символьно-буквальный суффикс ud (7)
строковый литерал ud-суффикс (8)

1-4) определяемые пользователем целочисленные литералы, например 12_km

5-6) определяемые пользователем литералы с плавающей запятой, такие как 0.5_Pa

7) определяемый пользователем символьный литерал, например ‘c’_X

8) определяемый пользователем строковый литерал, например «abd» _L или u «xyz» _M

десятично-буквальный То же, что и в целочисленном литерале, ненулевая десятичная цифра, за которой следует ноль или более десятичных цифр
восьмерично-буквальное То же, что и в целочисленном литерале, за которым следует ноль или более восьмеричных цифр
шестнадцатеричный литерал то же, что и в целочисленном литерале, 0x или 0X , за которым следует одна или несколько шестнадцатеричных цифр
двоично-буквальный то же, что и в целочисленном литерале, 0b или 0B , за которым следует одна или несколько двоичных цифр
последовательность цифр То же, что и в плавающем литерале, последовательность десятичных цифр
дробно-постоянная то же, что и в плавающем литерале, либо последовательность цифр, за которой следует точка (123.) или необязательная последовательность цифр, за которой следует точка и другая последовательность цифр (1.0 или .12)
экспонент-часть То же, что и в плавающем литерале, буква e или буква E , за которой следует необязательный знак, за которым следует последовательность цифр
символьно-буквальный то же, что и в символьном литерале
строковый литерал то же, что и в строковом литерале, включая необработанные строковые литералы
ud-суффикс идентификатор, представленный литеральным оператором или объявлением шаблона литерального оператора (см. Ниже).Все ud-суффиксы, вводимые программой, должны начинаться с символа подчеркивания _ . Суффиксы ud стандартной библиотеки не начинаются с подчеркивания.

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

(начиная с C ++ 14)

Если токен соответствует определенному пользователем буквальному синтаксису и обычному буквальному синтаксису, предполагается, что он является обычным литералом (то есть невозможно перегрузить LL в 123LL)

Когда компилятор встречает определенный пользователем литерал с ud-суффиксом X , он выполняет поиск неквалифицированного имени, ища функцию с именем operator "" X .Если поиск не находит объявления, программа имеет неправильный формат. Иначе,

1) Для определяемых пользователем целочисленных литералов

a) если набор перегрузки включает литеральный оператор с типом параметра unsigned long long, определяемое пользователем литеральное выражение обрабатывается как оператор вызова функции «» X (nULL), где n — литерал без суффикса ud

b) в противном случае набор перегрузки должен включать либо, но не оба, необработанный литеральный оператор или шаблон числового литерального оператора.Если набор перегрузки включает в себя необработанный литеральный оператор, определяемое пользователем литеральное выражение обрабатывается как оператор вызова функции «» X («n»)

c) в противном случае, если набор перегрузки включает шаблон оператора числового литерала, определяемое пользователем буквенное выражение обрабатывается как оператор вызова функции «» X <'c1', 'c2', 'c3' ..., 'ck '> (), где c1..ck — отдельные символы n .

2) Для определяемых пользователем литералов с плавающей запятой

a) Если набор перегрузки включает литеральный оператор с типом параметра long double, определяемое пользователем буквальное выражение обрабатывается как оператор вызова функции «» X (fL), где f — литерал без суффикса ud

b) в противном случае набор перегрузки должен включать либо, но не оба, необработанный литеральный оператор или шаблон числового литерального оператора.Если набор перегрузки включает в себя необработанный литеральный оператор, определяемое пользователем литеральное выражение обрабатывается как оператор вызова функции «» X («f»)

c) в противном случае, если набор перегрузки включает шаблон оператора числового литерала, определяемое пользователем буквенное выражение обрабатывается как оператор вызова функции «» X <'c1', 'c2', 'c3' ..., 'ck '> (), где c1..ck — отдельные символы f .

3) Для определяемых пользователем строковых литералов пусть str будет литералом без суффикса ud:

a) Если набор перегрузки включает шаблон оператора строкового литерала с параметром шаблона, не являющимся типом, для которого str является правильно сформированным аргументом шаблона, то определяемое пользователем литеральное выражение обрабатывается как оператор вызова функции «» X (),

(начиная с C ++ 20)

b) в противном случае определяемое пользователем литеральное выражение обрабатывается как оператор вызова функции «» X (str, len), где len — длина строкового литерала, исключая завершающий нулевой символ

4) Для определяемых пользователем символьных литералов выражение определяемого пользователем литерала обрабатывается как оператор вызова функции «» X (ch), где ch — литерал без суффикса ud

 long double оператор "" _w (long double);
std :: string operator "" _w (const char16_t *, size_t);
беззнаковый оператор "" _w (const char *);
int main () {
    1.2_w; // вызывает оператор "" _w (1.2L)
    u "один" _w; // вызывает оператор "" _w (u "one", 3)
    12_w; // вызывает оператор "" _w ("12")
    "два" _w; // ошибка: нет подходящего буквального оператора
} 

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

 int main () {
    L "A" "B" "C" _x; // ОК: то же, что L "ABC" _x
    "P" _x "Q" "R" _y; // ошибка: два разных ud-суффикса (_x и _y)
} 

[править] Литеральные операторы

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

Имя этой функции может иметь одну из двух форм:

оператор "" идентификатор
оператор определяемый пользователем строковый литерал
идентификатор идентификатор, который будет использоваться в качестве ud-суффикса для определяемых пользователем литералов, которые будут вызывать эту функцию.Должен начинаться с подчеркивания _ : суффиксы, которые не начинаются с подчеркивания, зарезервированы для литеральных операторов, предоставляемых стандартной библиотекой.
определяемый пользователем строковый литерал последовательность символов "" , за которой без пробела следует последовательность символов, которая становится суффиксом ud. Этот специальный синтаксис позволяет использовать ключевые слова языка и зарезервированные идентификаторы в качестве суффиксов ud и используется при объявлении оператора «» if из заголовка .Обратите внимание, что использование этой формы не изменяет правила, согласно которым определяемые пользователем буквенные операторы должны начинаться с подчеркивания: объявления, такие как оператор «», если могут появляться только как часть заголовка стандартной библиотеки. Однако он позволяет использовать подчеркивание, за которым следует заглавная буква (в противном случае это зарезервированный идентификатор).

Если литеральный оператор является шаблоном, он должен иметь пустой список параметров и может иметь только один параметр шаблона, который должен быть пакетом параметров шаблона без типа с типом элемента char (в этом случае он известен как шаблон оператора числового литерала )

 шаблон  двойной оператор "" _x (); 

или параметр шаблона без типа типа класса (в этом случае он известен как шаблон оператора строкового литерала )

 структура A {constexpr A (const char *); };

шаблон  Оператор "" _a (); 
(начиная с C ++ 20)

Для литеральных операторов разрешены только следующие списки параметров:

( const char * ) (1)
( беззнаковый длинный длинный int ) (2)
( длинный двойной ) (3)
( символ ) (4)
( wchar_t ) (5)
( char8_t ) (6) (начиная с C ++ 20)
( char16_t ) (7)
( char32_t ) (8)
( const char * , std :: size_t ) (9)
( const wchar_t * , std :: size_t ) (10)
( const char8_t * , std :: size_t ) (11) (начиная с C ++ 20)
( const char16_t * , std :: size_t ) (12)
( const char32_t * , std :: size_t ) (13)

1) Литеральные операторы с этим списком параметров — это необработанные литеральные операторы , используемые как резервные для целочисленных и определяемых пользователем литералов с плавающей запятой (см. Выше)

2) Литеральные операторы с этими списками параметров являются литералами первого выбора для определяемых пользователем целочисленных литералов

3) Литеральные операторы с этими списками параметров являются литеральными операторами первого выбора для определяемых пользователем литералов с плавающей запятой

4-8) Литеральные операторы с этими списками параметров вызываются определяемыми пользователем символьными литералами

9-13) Литеральные операторы с этими списками параметров вызываются определяемыми пользователем строковыми литералами

Аргументы по умолчанию не допускаются.

Привязка языка C не допускается.

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

 void operator "" _km (long double); // ОК, будет вызвано 1.0_km
std :: string operator "" _i18n (const char *, std :: size_t); // В ПОРЯДКЕ
шаблон  двойной оператор "" _π (); // В ПОРЯДКЕ
оператор с плавающей точкой "" _e (const char *); // В ПОРЯДКЕ

оператор с плавающей точкой "" Z (const char *); // ошибка: суффикс должен начинаться с подчеркивания
двойной оператор "" _Z (длинное двойное); // ошибка: все имена начинаются с подчеркивания
                                   // за которыми следует заглавная буква зарезервированы
двойной оператор "" _ Z (длинный двойной); // ОК: даже если _Z зарезервирован "" _Z разрешен 

[править] Примечания

С момента появления определяемых пользователем литералов код, использующий макроконстанты формата для целочисленных типов фиксированной ширины без пробела после предшествующего строкового литерала, стал недействительным: std :: printf («%» PRId64 «\ n», INT64_MIN) ; необходимо заменить на std :: printf («%» PRId64 «\ n», INT64_MIN);

Из-за максимального размера определяемые пользователем целочисленные литералы и литералы с плавающей запятой, оканчивающиеся на p , P , (начиная с C ++ 17) e и E , за которыми следуют операторы + или - , должно быть отделено от оператора пробелом или круглыми скобками в источнике:

 оператор long double "" _ E (long double);
длинный двойной оператор "" _ a (длинный двойной);
int оператор "" _ p (беззнаковый длинный длинный);

авто х = 1.0_E + 2.0; // ошибка
авто y = 1.0_a + 2.0; // В ПОРЯДКЕ
авто z = 1.0_E +2.0; // В ПОРЯДКЕ
авто q = (1.0_E) +2.0; // В ПОРЯДКЕ
авто w = 1_p + 2; // ошибка
авто u = 1_p +2; // ОК 

То же самое относится к оператору точки после целочисленного или определенного пользователем литерала с плавающей запятой:

 #include 
используя пространство имен std :: literals;
auto a = 4s.count (); // Ошибка
auto b = 4s .count (); // В ПОРЯДКЕ
авто c = (4s) .count (); // ОК 

В противном случае один недопустимый токен номера предварительной обработки (например,, 1.0_E + 2.0 или 4s.count), что приводит к сбою компиляции.

[править] Примеры

 #include 
#include <алгоритм>
#include 
#include <строка>

// используется как преобразование
constexpr long double оператор "" _deg (long double deg)
{
    возврат град * 3,14159265358979323846264L / 180;
}

// используется с произвольным типом
struct mytype
{
    беззнаковый длинный длинный м;
};
constexpr mytype operator "" _mytype (unsigned long long n)
{
    вернуть mytype {n};
}

// используется для побочных эффектов
void operator "" _print (const char * str)
{
    std :: cout << str << '\ n';
}

#if __cpp_nontype_template_args <201911

std :: string operator "" _x2 (const char * str, std :: size_t)
{
    вернуть std :: string {str} + str;
}

#else // Шаблон оператора строкового литерала C ++ 20

шаблон 
struct DoubleString
{
    char p [N * 2-1] {};

    constexpr DoubleString (char const (& pp) [N])
    {
        std :: range :: copy (pp, p);
        std :: range :: copy (pp, p + N - 1);
    };
};

шаблон 
constexpr автоматический оператор "" _x2 ()
{
    вернуть А.п;
}

#endif // C ++ 20

int main ()
{
    двойной x = 90.0_deg;
    std :: cout << std :: fixed << x << '\ n';
    mytype y = 123_mytype;
    std :: cout << y.m << '\ n';
    0x123ABC_print;
    std :: cout << "abc" _x2 << '\ n';
} 

Выход:

 1,570796
123
0x123ABC
abcabc 

[править] Стандартная библиотека

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

.

4.12 - Литералы | Learn C ++

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

Литеральные константы (обычно называемые просто литералами) - это значения, вставленные непосредственно в код. Например:

возврат 5; // 5 - целочисленный литерал

bool myNameIsAlex {true}; // true - это логический литерал

std :: cout << 3.4; // 3.4 - двойной литерал

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

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

По умолчанию:

Буквальное значение Примеры Тип по умолчанию
целое значение 5, 0, -3 внутр
логическое значение правда, ложь булев
значение с плавающей запятой 3.4, -2,2 двойной (не плавающий)!
значение символа ‘a’ знак
Стринги в стиле C «Привет, мир!» const char [14]

Буквенные суффиксы

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

л

л

Тип данных Суффикс Значение
внутр u или U целое число без знака
внутр л или длинный
внутр ul, uL, Ul, UL, lu, lU, Lu или LU беззнаковое длинное
внутр ll или LL длинный длинный
внутр ull, uLL, Ull, ULL, llu, llU, LLu или LLU беззнаковый длинный длинный
двойной F или F поплавок
двойной л или длинный двойной

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

беззнаковое целое значение1 {5u}; // 5 имеет тип unsigned int

long value2 {6L}; // 6 имеет тип long

По умолчанию буквальные константы с плавающей запятой имеют тип double .Чтобы вместо этого использовать литералы с плавающей запятой, следует использовать суффикс f (или F):

float f {5.0f}; // 5.0 имеет тип float

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

float f {4.1}; // предупреждение: 4.1 - это двойной литерал, а не литерал с плавающей запятой

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

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

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

В уроке 4.11 - Символы мы определили строку как набор последовательных символов. C ++ поддерживает строковые литералы:

std :: cout << "Привет, мир!"; // "Привет мир!" это строковый литерал в стиле C

std :: cout << "Hello," "world!"; // C ++ объединит последовательные строковые литералы

Строковые литералы обрабатываются в C ++ очень странно по историческим причинам.На данный момент можно использовать строковые литералы для печати текста с помощью std :: cout, но не пытайтесь назначать их переменным или передавать их функциям - это либо не сработает, либо не будет работать, как вы » буду ожидать. Мы поговорим больше о строках в стиле C (и о том, как обойти все эти странные проблемы) в будущих уроках.

Научная запись для литералов с плавающей запятой

Существует два разных способа объявления литералов с плавающей запятой:

двойной пи {3.-19

Восьмеричные и шестнадцатеричные литералы

В повседневной жизни мы считаем, используя десятичные числа, где каждая числовая цифра может быть 0, 1, 2, 3, 4, 5, 6, 7, 8 или 9. Десятичное число также называется «основанием 10», потому что есть 10 возможных цифр (от 0 до 9). В этой системе мы считаем так: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,… По умолчанию, числа в программах на C ++ считаются десятичными.

внутр x {12}; // 12 считается десятичным числом

В двоичном формате всего 2 цифры: 0 и 1, поэтому он называется «основанием 2».В двоичном формате мы считаем так: 0, 1, 10, 11, 100, 101, 110, 111,…

.

Есть две другие «основы», которые иногда используются в вычислениях: восьмеричная и шестнадцатеричная.

Octal - это основание 8, то есть доступны только цифры: 0, 1, 2, 3, 4, 5, 6 и 7. В Octal мы считаем так: 0, 1, 2, 3, 4 , 5, 6, 7, 10, 11, 12,… (примечание: нет 8 и 9, поэтому мы пропускаем от 7 до 10).

Десятичное 0 1 2 3 4 5 6 7 8 9 10 11
восьмеричный 0 1 2 3 4 5 6 7 10 11 12 13

Чтобы использовать восьмеричный литерал, добавьте к нему префикс 0:

#include

int main ()

{

int x {012}; // 0 перед числом означает, что это восьмеричное число

std :: cout << x;

возврат 0;

}

Эта программа напечатает:

10
 

Почему 10 вместо 12? Потому что числа печатаются в десятичном виде, а 12 в восьмеричном = 10 десятичном.

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

Шестнадцатеричный - это основание 16. В шестнадцатеричном мы считаем так: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12,…

Десятичное 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Шестнадцатеричный 0 1 2 3 4 5 6 7 8 9 A В С D E F 10 11

Чтобы использовать шестнадцатеричный литерал, поставьте перед литералом префикс 0x.

#include

int main ()

{

int x {0xF}; // 0x перед числом означает, что это шестнадцатеричный

std :: cout << x;

возврат 0;

}

Эта программа напечатает:

15
 

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

Рассмотрим 32-битное целое число со значением 0011 1010 0111 1111 1001 1000 0010 0110. Из-за длины и повторяемости цифр его нелегко прочитать. В шестнадцатеричном формате это же значение будет: 3A7F 9826. Это делает шестнадцатеричные значения полезными в качестве краткого способа представления значения в памяти. По этой причине шестнадцатеричные значения часто используются для представления адресов памяти или необработанных значений в памяти.

До C ++ 14 не было возможности назначать двоичный литерал. Однако шестнадцатеричные пары предоставляют нам полезный обходной путь:

1

2

3

4

5

6

7

8

9

10

11

12

13

140002

14

18

19

#include

int main ()

{

int bin {};

bin = 0x01; // присвоить двоичный 0000 0001 переменной

bin = 0x02; // присвоить двоичный код 0000 0010 переменной

bin = 0x04; // присвоить двоичный 0000 0100 переменной

bin = 0x08; // присвоить двоичный код 0000 1000 переменной

bin = 0x10; // присвоить двоичный код 0001 0000 переменной

bin = 0x20; // присвоить двоичный 0010 0000 переменной

bin = 0x40; // присвоить двоичный номер 0100 0000 переменной

bin = 0x80; // присвоить двоичный код 1000 0000 переменной

bin = 0xFF; // присвоить двоичный код 1111 1111 переменной

bin = 0xB3; // присвоить двоичный код 1011 0011 переменной

bin = 0xF770; // присвоить двоичный код 1111 0111 0111 0000 переменной

return 0;

}

C ++ 14 двоичные литералы и разделители цифр

В C ++ 14 мы можем назначать двоичные литералы с помощью префикса 0b:

#include

int main ()

{

int bin {};

bin = 0b1; // присвоить двоичный код 0000 0001 переменной

bin = 0b11; // присвоить двоичный 0000 0011 переменной

bin = 0b1010; // присвоить двоичный код 0000 1010 переменной

bin = 0b11110000; // присвоить двоичный код 1111 0000 переменной

return 0;

}

Поскольку длинные литералы трудно читать, в C ++ 14 также добавлена ​​возможность использования кавычек (‘) в качестве разделителя цифр.

#include

int main ()

{

int bin {0b1011'0010}; // присвоить двоичный код 1011 0010 переменной

long value {2'132'673'462}; // читать намного легче, чем 2132673462

return 0;

}

Если ваш компилятор несовместим с C ++ 14, он будет жаловаться, если вы попытаетесь использовать любой из них.

Печать десятичных, восьмеричных, шестнадцатеричных и двоичных чисел

По умолчанию C ++ выводит значения в десятичном формате. Однако вы можете указать ему печатать в других форматах. Печать в десятичном, восьмеричном или шестнадцатеричном формате упрощается благодаря использованию std :: dec, std :: oct и std :: hex:

#include

int main ()

{

int x {12};

std :: cout << x << '\ n'; // десятичный (по умолчанию)

std :: cout << std :: hex << x << '\ n'; // шестнадцатеричный

std :: cout << x << '\ n'; // теперь шестнадцатеричный

std :: cout << std :: oct << x << '\ n'; // восьмеричный

std :: cout << std :: dec << x << '\ n'; // возврат к десятичной системе

std :: cout << x << '\ n'; // десятичный

return 0;

}

Это отпечатки:

12
c
c
14
12
12
 

Печать в двоичном формате немного сложнее, поскольку std :: cout не имеет встроенной возможности.К счастью, стандартная библиотека C ++ включает тип std :: bitset, который сделает это за нас (в заголовке ). Чтобы использовать std :: bitset, мы можем определить переменную std :: bitset и указать std :: bitset, сколько бит мы хотим сохранить. Количество битов должно быть постоянной времени компиляции. std :: bitset может быть инициализирован целым значением без знака (в любом формате, включая десятичный, восьмеричный, шестнадцатеричный или двоичный).

#include // для std :: bitset

#include

int main ()

{

// std :: bitset <8> означает, что мы хотим сохранить 8 бит

std :: bitset <8> bin1 {0b1100'0101}; // двоичный литерал для двоичного 1100 0101

std :: bitset <8> bin2 {0xC5}; // шестнадцатеричный литерал для двоичного числа 1100 0101

std :: cout << bin1 << '' << bin2 << '\ n';

std :: cout << std :: bitset <4> {0b1010} << '\ n'; // мы также можем печатать напрямую из std :: bitset

return 0;

}

Это отпечатки:

11000101 11000101
1010
 

Мы также можем создать временный (анонимный) std :: bitset для печати одного значения.В приведенном выше коде эта строка:

std :: cout << std :: bitset <4> {0b1010} << '\ n'; // мы также можем печатать напрямую из std :: bitset

создает временный объект std :: bitset с 4 битами, инициализирует его с помощью 0b1010 , печатает значение в двоичном формате и затем отбрасывает временный std :: bitset.

Магические числа и почему они плохие

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

int maxStudents {numClassrooms * 30};

Число, такое как 30 в приведенном выше фрагменте, называется магическим числом.Магическое число - это литерал (обычно число) в середине кода, не имеющий никакого контекста. Что значит 30? Хотя вы, наверное, догадываетесь, что в данном случае это максимальное количество студентов в классе, это не совсем понятно. В более сложных программах может быть очень трудно сделать вывод, что представляет собой жестко запрограммированное число, если нет комментария, объясняющего это.

Использование магических чисел обычно считается плохой практикой, потому что, помимо того, что они не предоставляют контекст того, для чего они используются, они создают проблемы, если значение необходимо изменить.Предположим, школа покупает новые парты, которые позволяют увеличить размер класса с 30 до 35, и наша программа должна это отразить. Рассмотрим следующую программу:

int maxStudents {numClassrooms * 30};

setMax (30);

Чтобы обновить нашу программу для использования нового размера класса, нам нужно обновить константу 30 до 35. Но как насчет вызова setMax ()? Имеют ли эти 30 то же значение, что и остальные 30? Если да, то его следует обновить.Если нет, его следует оставить в покое, иначе мы можем сломать нашу программу где-нибудь еще. Если вы выполняете глобальный поиск и замену, вы можете случайно обновить аргумент setMax (), когда он не должен был изменяться. Таким образом, вам нужно просмотреть весь код для каждого экземпляра литерала 30, а затем определить, нужно ли его изменить или нет. Это может занять много времени (и привести к ошибкам).

Хотя мы говорим «магические числа», это влияет на все виды значений. Рассмотрим этот пример

std :: cout << "Введите число меньше 100:";

int input {};

std :: cin >> input;

if (input> = 100)

{

std :: cout << "Неверный ввод! Число должно быть меньше 100.";

}

В этом примере только одно число (100), но оно также используется в строках. Если мы решим обновить максимальное количество, скажем, 200, нам придется обновить три разных случая по 100.

К счастью, существуют лучшие варианты (символьные константы). Об этом мы поговорим на следующем уроке.

Не используйте магические числа в своем коде.

.

Переменные, литералы и константы C ++

Переменные C ++

В программировании переменная - это контейнер (область хранения) для хранения данных.

Чтобы указать область хранения, каждой переменной должно быть присвоено уникальное имя (идентификатор). Например,

  int age = 14;
  

Здесь age - это переменная типа данных int , и мы присвоили ей целое значение 14.

Примечание: Тип данных int предполагает, что переменная может содержать только целые числа.Точно так же мы можем использовать тип данных double , если нам нужно хранить десятичные дроби и экспоненты.

Мы подробно узнаем обо всех типах данных в следующем руководстве.

Значение переменной можно изменить, отсюда и название переменная .

  int age = 14; // возраст 14
возраст = 17; // возраст 17
  

Правила присвоения имени переменной

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

Примечание: Мы должны попытаться дать значимые имена переменным. Например, first_name - лучшее имя переменной, чем fn .


Литералы C ++

Литералы - это данные, используемые для представления фиксированных значений. Их можно использовать прямо в коде. Например: 1 , 2,5 , 'c' и т. Д.

Здесь 1 , 2,5 и 'c' - литералы. Почему? Вы не можете присвоить этим условиям разные значения.

Вот список различных литералов в программировании на C ++.


1. Целые числа

Целое число - это числовой литерал (связанный с числами) без дробной или экспоненциальной части.В программировании на C есть три типа целочисленных литералов:

  • десятичное (основание 10)
  • восьмеричный (основание 8)
  • шестнадцатеричный (основание 16)

Например:

Десятичный: 0, -9, 22 и т. Д.
Восьмеричный: 021, 077, 033 и т. Д.
Шестнадцатеричный: 0x7f, 0x2a, 0x521 и т. Д.
 

В программировании на C ++ восьмеричное начинается с 0 , а шестнадцатеричное - с 0x .


2. Литералы с плавающей запятой

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

-2,0

0,0000234

-0.22E-5

Примечание: E-5 = 10 -5


3. Персонажи

Символьный литерал создается заключением одного символа в одинарные кавычки. Например: 'a' , 'm' , 'F' , '2' , '}' и т. Д.


4. Последовательности побега

Иногда необходимо использовать символы, которые нельзя ввести или которые имеют особое значение в программировании на C ++.Например, новая строка (ввод), табуляция, вопросительный знак и т. Д.

Для использования этих символов используются escape-последовательности.

Последовательности побега Персонажи
\ b Backspace
\ f Подача формы
\ n Новая строка
\ r Возврат
\ т Горизонтальная вкладка
\ v Вертикальный язычок
\ Обратная косая черта
\ ' Одинарные кавычки
\ " Двойные кавычки
\? Вопросительный знак
\ 0 Нулевой символ

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

Строковый литерал - это последовательность символов, заключенная в двойные кавычки. Например:

«хорошо» строковая константа
" константа пустой строки
" строковая константа из шести пробелов
"x" строковая константа, содержащая один символ
"Земля круглая \ n" печатает строку с новой строкой

Подробнее о строках мы узнаем в учебнике по строкам C ++.


Константы C ++

В C ++ мы можем создавать переменные, значение которых нельзя изменить. Для этого мы используем ключевое слово const . Вот пример:

  const int LIGHT_SPEED = 299792458;
LIGHT_SPEED = 2500 // Ошибка! LIGHT_SPEED - постоянная величина.
  

Здесь мы использовали ключевое слово const для объявления константы с именем LIGHT_SPEED . Если мы попытаемся изменить значение LIGHT_SPEED , мы получим ошибку.

Константу также можно создать с помощью директивы препроцессора #define . Мы узнаем об этом подробно в руководстве по макросам C ++.

.

строковых литералов - cppreference.com

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

[править] Синтаксис

" s-char-последовательность " (1)
u8 " s-char-sequence " (2) (начиная с C11)
u " s-char-последовательность " (3) (начиная с C11)
U " s-char-последовательность " (4) (начиная с C11)
L " s-char-последовательность " (5)

где

s-char-последовательность - ноль или более символов, каждый из которых является либо многобайтовым символом из исходного набора символов (исключая ( " ), \ и символ новой строки), либо escape-символом, шестнадцатеричным escape-кодом, восьмеричным escape-кодом или унифицированное имя символа (начиная с C99), как определено в escape-последовательностях.

1) литерал символьной строки : Тип литерала - char [N], где N - размер строки в единицах кода узкой кодировки исполнения, включая нулевой признак конца. Каждый элемент char в массиве инициализируется со следующего символа в s-char-последовательности с использованием набора символов выполнения.

2) Строковый литерал UTF-8 : Тип литерала - char [N], где N - размер строки в единицах кода UTF-8, включая нулевой признак конца.Каждый элемент char в массиве инициализируется следующим многобайтовым символом в s-char-последовательности с использованием кодировки UTF-8.

3) 16-битный строковый литерал: Тип литерала - char16_t [N], где N - размер строки в единицах кода 16-битной кодировки, определяемой реализацией (обычно UTF-16), включая нулевой терминатор. Каждый элемент char16_t в массиве инициализируется, как если бы он выполнял mbrtoc16 в локали, определяемой реализацией.
4) 32-битный строковый литерал: типом литерала является char32_t [N], где N - размер строки в единицах кода 32-битной кодировки, определяемой реализацией (обычно UTF-32), включая нулевой терминатор.Каждый элемент char32_t в массиве инициализируется, как если бы он выполнял mbrtoc32 в локали, определяемой реализацией.
5) широкий строковый литерал: типом литерала является wchar_t [N], где N - размер строки в единицах кода широкой кодировки исполнения, включая нулевой терминатор. Каждый элемент wchar_t в массиве инициализируется, как если бы он выполнял mbstowcs в локали, определяемой реализацией.

[править] Объяснение

Во-первых, на этапе перевода 6 (после раскрытия макроса) смежные строковые литералы (то есть строковые литералы, разделенные только пробелами) объединяются.

Можно объединить только два узких или два широких строковых литерала.

(до C99)

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

 L "Δx =%" PRId16 // в фазе 4 PRId16 расширяется до "d"
                 // на этапе 6 L "Δx =%" и "d" образуют L "Δx =% d" 
(начиная с C99)

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

 char * p = "\ x12" "3"; // создает статический массив char [3], содержащий {'\ x12', '3', '\ 0'}
                      // устанавливает p, чтобы указать на первый элемент массива 

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

 char * p = "Привет";
p [1] = 'М'; // Неопределенное поведение
char a [] = "Привет";
а [1] = 'М'; // ОК: a не строковый литерал 

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

 "def" == 3+ "abcdef"; // может быть 1 или 0, определяется реализацией 

[править] Примечания

Строковый литерал не обязательно является строкой; если строковый литерал имеет встроенные нулевые символы, он представляет собой массив, содержащий более одной строки:

 char * p = "abc \ 0def"; // strlen (p) == 3, но размер массива 8 

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

 // char * p = "\ xfff"; // ошибка: шестнадцатеричная escape-последовательность вне допустимого диапазона
char * p = "\ xff" "е"; // хорошо, литерал char [3], содержащий {'\ xff', 'f', '\ 0'} 

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

 char a1 [] = "abc"; // a1 - это char [4], содержащий {'a', 'b', 'c', '\ 0'}
char a2 [4] = "abc"; // a2 - это char [4], содержащее {'a', 'b', 'c', '\ 0'}
char a3 [3] = "abc"; // a3 - это char [3], содержащая {'a', 'b', 'c'} 

Кодирование символьных строковых литералов (1) и широких строковых литералов (5) определяется реализацией.Например, gcc выбирает их с помощью параметров командной строки -fexec-charset и -fwide-exec-charset.

[править] Пример

 #include 
#include 
#include 
#include 
#include 
int main (пусто)
{
    char s1 [] = "а 🍌"; // или "a \ u732B \ U0001F34C"
    char s2 [] = u8 "а 猫 🍌";
    char16_t s3 [] = u "а 🍌";
    char32_t s4 [] = U "а 猫 🍌";
    wchar_t s5 [] = L "а 🍌";

    setlocale (LC_ALL, «en_US.utf8»);
    printf ("\"% s \ "- это символ [% zu], содержащий {", s1, sizeof s1 / sizeof * s1);
    для (size_t n = 0; n 

Возможный выход:

  «a 猫 🍌» - это символ [9], содержащий {0x61 0xE7 0x8C 0xAB 0xF0 0x9F 0x8D 0x8C 0x00}
u8 «a 猫 🍌» - это символ [9], содержащий {0x61 0xE7 0x8C 0xAB 0xF0 0x9F 0x8D 0x8C 0x00}
 u «a 猫 🍌» - char16_t [5], содержащий {0x0061 0x732B 0xD83C 0xDF4C 0x0000}
 U "a 猫 🍌" - это char32_t [4], содержащий {0x00000061 0x0000732B 0x0001F34C 0x00000000}
 L "a 猫 🍌" - это wchar_t [4], содержащий {0x00000061 0x0000732B 0x0001F34C 0x00000000} 

[править] Ссылки

  • C11 стандарт (ISO / IEC 9899: 2011):
  • 6.4.5 Строковые литералы (стр. 70-72)
    Стандарт

  • C99 (ISO / IEC 9899: 1999):
  • 6.4.5 Строковые литералы (стр: 62-63)
  • Стандарт C89 / C90 (ISO / IEC 9899: 1990):

[править] См. Также

.

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

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