Що таке літерал у С
Числові, логічні літерали та літерали-покажчики
Літерал - це елемент програми, який безпосередньо представляє значення У цій статті розглядаються літерали цілого типу, з плаваючою комою, логічне значення та вказівник. Ви можете визначити власні літерали на основі будь-якої з цих категорій. Додаткові відомості див. літерали" (C++).
Літерали можна використовувати в багатьох контекстах, але найчастіше вони використовуються для ініціалізації іменованих змінних та передачі аргументів у функції.
const int answer = 42; // integer literal double d = sin(108.87);
Іноді важливо вказувати компілятору, як слід обробляти літерал чи якийсь конкретний тип йому надати шляхом додавання префіксів або суфіксів до літералу. розглядати значення як unsigned long long тип, як у 5894345ULL . Повний список префіксів та суфіксів для кожного типу літералу див. у наступних розділах.
Цілочисленні літерали
Цілочисленні літерали починаються з цифри і не мають дрібних частин або експонент.
Якщо префікс або суфікс відсутній, компілятор дасть цілісному літеральному типу (32 біта), якщо значення буде відповідати, інакше він дасть йому тип int long long (64 біти).
Щоб вказати десятковий цілий літерал, починайте специфікацію з будь-якої цифри, крім нуля. Наприклад:
int i = 157; // Decimal literal int j = 0198; // Not a decimal number; erroneous octal literal int k = 0365; // Leading zero specifies octal literal, no decimal int m = 36'000'000 // digit separators make large values more readable
Щоб вказати восьмеричний цілочисленний літерал, починайте специфікацію з нуля, за яким слідує ряд цифр у діапазоні від 0 до 7. Цифри 8 і 9 при вказівці восьмеричного літералу будуть помилками. Наприклад:
int i = 0377; // Octal literal int j = 0397; // Error: 9 is not an octal digit
Щоб вказати шістнадцятковий цілочисленний літерал, почніть специфікацію з 0x або (у разі "x" не має значення), за якою слідує послідовність цифр в діапазоні 0 і a 9 (або) через f (або F A 0X ). Шістнадцяткові цифри від a (або A ) до f (або F ) являють собою значення в діапазоні від 10 до 15. Наприклад:
int i = 0x3fff; // Hexadecimal literal int j = 0X3FFF; // Equal to i
Щоб вказати непідписаний тип, використовуйте суфікс u або U. Щоб вказати довгий тип, використовуйте l або суфікс L . Для вказівки 64-розрядного цілого типу використовується суфікс LL або ll. Суфікс i64, як і раніше, підтримується, але ми не рекомендуємо його. Він залежить від корпорації Майкрософт і не переносимо. Наприклад:
unsigned val_1 = 328u; // Unsigned value long val_2 = 0x7FFFFFL; // Long value specified // як hex literal unsigned long val_3 = 0776745ul; // Unsigned long value auto val_4 = 108LL; // signed long long auto val_4 = 0x8000000000000000ULL
Розділювачі цифр: можна використовувати символ з одним лапками (apostrophe) для розділення значень у великих числах, щоб спростити читання для людей. Розділювачі не впливають на компіляцію.
long long i = 24'847'458'121;
Літерали з плаваючою комою
Літерали з плаваючою комою задають значення, які повинні мати дрібну частину. Ці значення містять десяткові знаки ( . ) і можуть містити експоненти.
Літерали з плаваючою комою мають символіку (іноді звану мантисою), яка задає значення числа. Вони мають експонентщо вказує величину числа. І вони мають необов'язковий суфікс, що вказує тип літералу. Знак вказується у вигляді послідовності цифр, за яким слідує період, за яким слідує необов'язкова послідовність цифр, що становить дробову частину числа. Наприклад:
Якщо вказано показник ступеня, він визначає порядок числа у вигляді ступеня 10, як показано в наступному прикладі:
18.46e0 // 18.46 18.46e1 // 184.6
Експонент може бути вказаний за допомогою e або E, які мають те ж значення, за яким слідує необов'язковий знак (+ або -) та послідовність цифр. Якщо вказано показник ступеня, то десяткова точка в кінці цілих чисел не потрібна, наприклад 18E0 .
Літерали з плаваючою комою за замовчуванням для типу double . Використовуючи суфікси f або F L L (суфікс не враховує регістр), літерал можна вказати як float або. long double
Хоча long double і double мають те саме уявлення, вони не однакові. Наприклад, у вас можуть бути перевантажені функції, такі як
void func (long double);
логічні літерали
Логічні літерали та true false .
Літерал-покажчик (C++11)
C++ вводить nullptr літерал для вказівки покажчика з нульовою ініціалізацією. У коді, що переноситься nullptr слід використовувати замість цілого нуля або макросів, таких як NULL .
Двійкові літерали (C++14)
Двійковий літерал можна задати за допомогою префікса 0B або 0b і послідовності, що складається з 1 та 0:
auto x = 0B001101; // int auto y = 0b000001; // int
Уникайте використання літералів як магічних констант
Незважаючи на те, що це не завжди є хорошим стилем програмування, можна використовувати літерали безпосередньо у виразах та операторах:
У попередньому прикладі рекомендується використовувати іменовану константу, яка передає чітке значення, наприклад "MAXIMUM_ERROR_THRESHOLD". І якщо значення "Success", що повертається, відображається кінцевими користувачами, можливо, краще використовувати іменовану константу рядка. Рядкові константи можна зберігати в одному розташуванні у файлі, який можна локалізувати іншими мовами. Використання іменованих констант допомагає і собі, і іншим користувачам зрозуміти намір коду.
Визначені користувачем літерали
Існує шість основних категорій літералів у C++: ціле число, символ, плаваюча точка, рядок, логічне значення та покажчик. Починаючи з C++11, можна визначити власні літерали на основі цих категорій, щоб забезпечити синтаксичні поєднання клавіш для поширених ідіом і підвищити безпеку типів. Наприклад, припустимо, що у вас є клас Distance. Можна визначити літерал для кілометрів і ще один для миль, і заохочувати користувача бути явним в одиницях виміру шляхом написання auto d = 42.0_km або auto d = 42.0_mi . Немає переваг продуктивності або нестачі для літералів, що визначаються користувачем; вони переважно для зручності чи відрахування типів під час компіляції. У стандартній бібліотеці є літерали, що визначаються користувачем, для std::string std::complex і для одиниць часу і тривалості операцій в заголовку :
Distance d=36.0_mi + 42.0_km; // Custom UDL (see below) std::string str = "hello"s + "World"s; // Standard Library UDL complex num = (2.0 + 3.01i) * (5.0 + 4.3i); // Standard Library UDL auto duration = 15ms + 42h; // Standard Library UDLs
Сигнатури, що визначаються користувачем літеральних операторів
Ви реалізуєте літерал, що визначається користувачем, визначаючи оператор "" в області простору імен з однією з наступних форм:
ReturnType operator "" _a(unsigned long long int); // Literal operator for user-defined INTEGRAL literal ReturnType operator "" _b(long double); // Literal operator for user-defined FLOATING literal ReturnType operator "" _c(char); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _d(wchar_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _e(char16_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _f(char32_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _g(const char*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _h(const wchar_t*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _i(const char16_t*, size_t); // Literal operator для user-defined STRING literal ReturnType operator "" _g(const char32_t*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _r(const char*); // Raw literal operator template ReturnType operator "" _t(); // Literal operator template
Імена операторів, які були використані в попередньому прикладі, можна замінити на будь-які інші. Обов'язковою є лише символ підкреслення на початку. (Тільки стандартна бібліотека може визначати літерали без підкреслення.) Тип значення, що повертається — це спосіб налаштування перетворення або інших операцій, що виконуються літералом. Крім того, всі ці оператори можуть бути визначені як constexpr .
Літерали з обробкою
У вихідному коді будь-який літерал, визначений користувачем чи ні, по суті, є послідовністю буквено-цифрових символів, таких як 101 або 54.7 або "hello" true . Компілятор інтерпретує послідовність як ціле число, рядок float, const char* тощо. буд. літералом. Всі оператори, описані вище, за винятком _r і _t є літералами з обробкою. Наприклад, літерал 42.0_km буде прив'язаний до оператора з ім'ям _km, що має сигнатуру схожу на _b, а літерал 42_km буде прив'язаний до оператора з сигнатурою схожою на _a.
У наступному прикладі показано, як літерали, що визначаються користувачем, можуть вимагати від користувачів явно вказувати вхідні дані. Щоб створити Distance , користувач повинен явно вказати кілометри або милі за допомогою відповідного літералу користувача. Ви можете досягти того ж результату іншими способами, але літерали, що визначаються користувачем, менш докладні, ніж альтернативні.
// UDL_Distance.cpp #include #include struct Distance < private: explicit Distance(long double val) : kilometers(val) <>friend Distance operator"" _km(long double val); friend Distance operator"" _mi(long double val); long double kilometers< 0 >; public: const static long double km_per_mile; long double get_kilometers() < return kilometers; >Distance operator+(Distance other) < return Distance(get_kilometers() + other.get_kilometers()); >>; const long double Distance::km_per_mile = 1.609344L; Distance operator"" _km(long double val) < return Distance(val); >Distance operator"" _mi(long double val) < return Distance(val * Distance::km_per_mile); >int main() < // Must have decimal point to bind to the operator we defined! Distance d<402.0_km>; // construct using kilometers std::cout; // construct using miles std::cout Необроблені літерали У необробленому літералі користувача оператор, який визначається, приймає літерал у вигляді послідовності значень char. Ви можете інтерпретувати цю послідовність як число чи рядок чи інший тип. У списку операторів, наведеному раніше на цій сторінці, є оператори, _r і _t, які можна використовувати для визначення необроблених літералів:
ReturnType operator ""_r(const char*); // Raw literal operator template ReturnType operator "" _t(); // Literal operator template
Необроблені літерали можна використовувати для надання інтерпретації вхідної послідовності, відмінної від нормальної поведінки компілятора. Наприклад, ви можете визначити літерал, що перетворює послідовність 4.75987 в тип десяткового числа замість типу з плаваючою комою за стандартом IEEE 754. Необроблені літерали, такі як приготовлені літерали, також можна використовувати для перевірки вхідних послідовностей під час компіляції.
приклад. Обмеження необробленого літералу
Оператор необробленого літералу і шаблон оператора літерала працюють тільки з літералами користувача, що мають цілочисельний тип або тип числа з плаваючою комою, як показано в наступному прикладі.
#include #include // Literal operator for user-defined INTEGRAL literal void operator "" _dump(unsigned long long int lit) < printf("operator \"\" _dump(unsigned long long int) : ===>%llu; // Literal operator for user-defined FLOATING literal void operator "" _dump(long double lit) < printf("operator \"\" _dump(long double) : ===>%Lf; // Literal operator for user-defined CHARACTER literal void operator "" _dump(char lit) < printf("operator \ "\" _dump(char) : ===>%c; lit) < printf("operator \"\" _dump(wchar_t) : ===>%d; void operator "" _dump(char16_t lit) < printf("operator \"\" _dump(char16_t) : ===> %d; void operator "" _dump(char32_t lit) < printf("operator "" _dump(char32_t) : ===>%d; size_t): ===>%s; lit, size_t) < printf("operator \"\" _dump(const wchar_t*, size_t): ===>%ls; void operator "" _dump(const char16_t* lit, size_t) < printf("operator \"\" _dump(const char16_t*, size_t):\n" ); >; void operator "" _dump(const char32_t* lit, size_t) < printf("operator \"\" _dump(const char32_t*, size_t):\n" ); >; // Raw literal operator void operator "" _dump_raw(const char* lit) < printf("operator \"\" _dump_raw(const char*) : ===>%s; template void operator "" _dump_template(); // Literal operator template int main(int argc, const char* argv[]) < 42_dump; 3.1415926_dump; 'A'_dump; -8 String"_dump; u"UTF-16 String"_dump; U"UTF-32 String"_dump; 42_dump_raw; 3.1415926_dump_raw; 3.14e+25_dump_raw; L'B'_dump_raw; // u'C'_dump_raw; // "Hello World"_dump_raw; // L"Wide String"_dump_raw; // u"UTF-16String"_dump_raw; // U"UTF-32 String"_dump_raw; >
operator "" _dump(unsigned long long int) : ===>423.14159331399999999999998506827776.000000A666768Hello WorldWide StringUTF-8 String423.15159
Що таке літерал у С++
У С++ є набір вбудованих типів даних для представлення цілих і дійсних чисел, символів, а також тип даних символьний масив, який служить для зберігання символьних рядків. Тип 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, він сприймається як вісімковий, якщо з 0х або 0Х, то як шістнадцятковий. Звичний запис сприймається як десяткове число.
За замовчуванням усі цілі літерали мають тип signed int. Можна явно визначити цілий літерал як має тип long, приписавши в кінці числа букву L (використовується як велика L, так і мала l, проте для зручності читання не слід вживати рядку: її легко переплутати з
1). Літера U (або u) в кінці визначає літерал як unsigned int, а дві літери – UL або LU – як тип unsigned long. Наприклад:
Літерали, що представляють дійсні числа, можуть бути записані як із десятковою точкою, так і в науковій (експоненційній) нотації. За замовчуванням вони мають тип double. Для явного вказівки типу float потрібно використовувати суфікс F чи f, а long double - L чи l, але у разі записи з десятковою точкою. Наприклад:
3.14159F 0/1f 12.345L 0.0 3el 1.0E-3E 2. 1.0L
Слова true та false є літералами типу bool.
Літеральні символьні константи записуються як символи в одинарних лапках. Наприклад:
Спеціальні символи (табуляція, повернення каретки) записуються як 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), компілятор з'єднує в одну рядок. Наприклад, наступний текст
породить масив із восьми символів – twosome і завершальний нульовий символ. Результат конкатенації рядків різного типу не визначено. Якщо написати:
// this is not a good idea "two" L"some"
то на якомусь комп'ютері результатом буде деякий осмислений рядок, а на іншому може виявитися щось зовсім інше. Програми, що використовують особливості реалізації того чи іншого компілятора чи операційної системи, є нестерпними. Ми не рекомендуємо користуватися такими конструкціями.
Вправа 3.1
Поясніть різницю у визначеннях наступних літералів:
(a) 'a', L'a', "a", L"a" (b) 10, 10u, 10L, 10uL, 012, 0*C (c) 3.14, 3.14f, 3.14L
Вправа 3.2
Які помилки допущені у наведених нижче прикладах?
(a) "Яка мова з F\144rgus?\014" (b) 3.14e1L (c) "two" L"some" (d) 1024f (e) 3.14UL (f) "multiple line comment"
Цікава стаття, спасибі) Ваш сайт - другий за важливістю ресурс після Кернігана та Річі:D
Подібні статті
- Що це таке місячні
- Що це таке трейлер
- Що таке ефект собаки Павлова
- Що таке цисти артемія
- Що таке чорні павуки з білими плямами
- Що таке яйця артемії
- Що таке часте мелірування
- Що таке експлікація будівель