asyan.org
добавить свой файл
1
Лекція 2. Константи (літерали).

Константа – це лексема, що є зображенням фіксованого числового, рядкового чи символьного (літерного) значення. У мові С++ визначені кілька видів літералів : цілі, дійсні ( з плаваючою крапкою), перелічні, символьні (літерні) та рядкові (рядки та літерні рядки). Перелічні константи відносяться у С++ до одного з цілочислових типів. Компілятор, виділивши константу як лексему, відносить її до деякої групи, а у групі – до деякого типу даних за її написанням у вхідному тексті та за числовим значенням.

Цілі константи.

Всі цілі константи, які складаються з послідовності цифр, є десятковими, якщо не починаються від нуля. Наприклад, 16, 484216, 0, 4. Для реалізації ВС++ та ТС++ діапазон допустимих цілих додатніх значень від 0 до 4294967295. Константи, що перевищують вказане максимальне значення, призводять до помилки при компіляції. Від’ємні константи – це константи без знаку, до яких застосована операція зміни знаку. Абсолютні значення від’ємних десяткових констант для ВС+ не більше від 2147483648.

Діапазони значень констант

Тип даних

десяткові

вісімкові

шістнадцяткові

від 0 до 32767

від 00 до 077777

від 0х0000 до 0х7FFF

int

-

від 0100000 до 0177777

від 0x8000 до 0xFFFF

unsigned int

від 32768 до 2147483647

від 0200000

до 017777777777

від 0x10000 до 0x7FFFFFFF

long

від 2147483648 до 4294967295

від 02000000000

до 037777777777

від 0x80000000

до 0xFFFFFFFF

unsigned long

>4294967295

>037777777777

>0xFFFFFFFF

помилка

Послідовність цифр, що починається від 0, є вісімковим цілим. Наприклад, 016 має десяткове значення 14. Якщо у запису вісімкової константи є недопустима цифра 8 чи 9, тоді це сприймається як помилка. У реалізаціях ТС++ та ВС++ діапазон допустимих значень для додатніх вісімкових констант від 00 до 37777777777. Для від’ємної вісімкової константи абсолютне значення на повинне перевищувати 0200000000000. Послідовність цифр, що починається від 0х чи 0Х,є шістнадцятковим цілим, вона може містити символи від А до F чи від a до f з десятковими значеннями. Наприклад, 0х16 має десяткове значення 22, а 0xF – десяткове значення 15. Діапазон допустимих значень для додатніх шістнадцяткових констант у реалізаціях ТС++ та ВС++ від 0х0 до 0xFFFFFFFF. Для від’ємних шістнадцяткових констант абсолютні значення не повинні перевищувати 0х80000000. Запис цілої константи визначає її тип.

Значення цілої константи визначає її відтворення в пам’яті ЕОМ компілятором. Форма відтворення визначається типом даних. Таблиця (стандарт ANSI для C) містить відповідність значень констант та автоматично вибраного компілятором типу. Можна змінити тип константи, користуючись суфіксами L, l (long) та U,u (unsigned). Наприклад, константа 64L матиме тип long, тоді як компілятор при замовчуванні надасть їй тип int ( за таблицею). Для однієї константи можна застосувати два суфікси U(u) та L(l) у довільному порядку. Наприклад, константи 0x22Ul, 0x11Lu, 0x330000UL, 0x55lu будуть мати тип unsigned long. При використанні одного суфікса вибирається той тип даних, який найбільше відповідає типу, що вибирається при замовчуванні (тобто без суфікса). Наприклад, 04L – константа типу long, 04U має тип unsigned int.

Символьні константи.

Це один чи кілька символів, обмежених з обох боків апострофами, наприклад, ‘x‘. Значенням константи з одного символа є порядковий номер символа у таблиці ASCII – кодів. Символьні константи з кількох символів відтворюються залежно від реалізації мови.

Для ілюстрації впливу абсолютного значення константи та використаних для неї суфіксів L,U на тип даних, наданий при компіляції, розглянемо наступну програму:

//Les2_1.CPP

#include

void main() { cout<< “\n sizeof 111=”<< sizeof111; // 2 байти

cout<< “\n sizeof 111u=”<< sizeof111u;// 2 байти

cout<< “\n sizeof 111L=”<< sizeof111L;// 4 байти

cout<< “\n sizeof 111ul=”<< sizeof111ul;// 4 байти

cout<< “\n sizeof 40000=”<< sizeof40000; // 4 байти

cout<< “\n sizeof 40000u=”<< sizeof40000u; // 2 байти

cout<< “\n sizeof 40000L=”<< sizeof40000L; // 4 байти

cout<< “\n sizeof 40000LU=”<< sizeof40000LU; // 4 байти }

Тут використана унарна операція мови С++ sizeof, яка дає змогу визначити розмір у байтах пам’яті, відведеної для записаного з правого боку операнда.

Зверніть увагу на довжину десяткової константи 40000u, яка відповідає типу unsigned int. При замовчуванні такий тип не надається ніякій константі, як це видно з таблиці.

Константи з плаваючою крапкою (дійсні).

При однаковому запису дійсні константи відрізняються формою внутрішнього відтворення в ЕОМ, яка вимагає використання арифметики з плаваючою крапкою при операціях з такими константами. Компілятор розпізнає такі константи за зовнішніми признаками: ціла частина (десяткова ціла константа); десяткова крапка; дробна частина (десяткова ціла константа); признак (символ) експоненти е чи Е; показник десяткового степеня (десяткова ціла константа, можливо зі знаком); суфікс F (чи f) або L(чи l).

У записах дійсних констант можна не записувати: цілу чи дробну частину (але не одночасно); десяткову крапку чи признак експоненти з показником степеня ( але не одночасно); суфікс. Приклади запису дійсних констант:

66. .0 .12 3.14159F 1.12e-2 2E+6L 2.7l

При відсутності суфіксів F(f) чи L(l) дійсні константи мають форму внутрішнього відтворення, що відповідає у С++ типу даних double. Додавши суфікс f чи F , константі надають тип float. Константа має тип long double, коли у її відтворенні використовується суфікс L чи l. Діапазони можливих значень та довжини внутрішнього відтворення ( розмір у бітах) даних дійсного типу наведені у таблиці:

Тип даних

Розмір, біт

Діапазон значень

float

32

від 3.4T-38 до 3.4E+38

double

64

від 1.7E-308 до 1.7E+308

long double

80

від 3.4E-4932 до 1.1E+4932

Наступна програма показує, які дільниці пам’яті відводяться дійсним константам різного типу у реалізаціях ТС++ та ВС++.

//Les2_2.CPP

#include

void main () { cout << “\n sizeof 3.141592653589793=”;// 8 байт

cout << sizeof 3.141592653589793; // 8 байт

cout << “\n sizeof 3.14159=”<< sizeof 3.14159; // 8 байт

cout << “\n sizeof 3.14159f=”<< sizeof 3.14159f; // 4 байти

cout << “\n sizeof 3.14159L=”<< sizeof 3.14159L; // 10 байт }

Перелічні константи (константи переліку, а також константи перелічного типу).

Такі константи оголошуються службовим словом enum. Це звичайні цілочислові константи (типу int), яким надані унікальні та зручні для використання позначення у вигляді довільних ідентифікаторів, що не співпадають зі службовими словами та іменами інших об’єктів програми. Позначення надаються, наприклад, таким визначенням: enum ( one=1, two=2, three=3};

Тут enum – службове слово, що визначає тип даних “перелік”. оne, two, three – умовні імена, введені програмистом для позначення констант 1,2,3. Тепер у програмі замість константи 2 ( і разом з нею) можна користуватися її позначенням two.

Якщо у визначенні перелічних констант не записувати знаки “=” та не вказувати числових значень, тоді вони будуть надаватися ідентифікаторам (іменам) при замовчуванні, коли найлівіший у фігурних дужках ідентифікатор набуде значення 0, а кожен наступний буде збільшуватися на 1.

Наприклад, відповідно до визначення enum {zero,one,two,three};

перелічні константи набудуть значень: zero==0, one==1, two==2,three==3

Правило про послідовне збільшення на 1 значень перелічних констант дії і тоді, коли першим з них ( зліва у списку) надані значення. Наприклад, визначення

enum {ten=10, three=3,four,five,six};

вводить такі константи: ten==10, three==3,four==4,five==5,six==6

Імена перелічних констант повинні бути унікальними, проте до значень констант це не відноситься. Одне значення можна надавати різним константам. Наприклад, визначення enum { zero,nought=0, one, two,paiz=2,three};

Вводить наступні константи: zero==0, nought==0, one==1,two==2,paiz==2, three==3

Значення, надані перелічним константам, можна задавати цілочисловими константами чи виразами. Наприклад,

enum { two=2, four=two*2}; визначить константи two==2 four==4

Оскільки від’ємна константа – це константа без знаку, до якої застосована унарна операція “-“(мінус), тому перелічним константам надаються від’ємні значення.

Для перелічних констант можна ввести ім’я типу, яке відповідає наведеному списку констант. Ім’я типу – це довільно вибраний ідентифікатор, записаний між службовим словом enum та відкритою фігурною дужкою. Наприклад, визначення

enum week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

не лише визначає константи Sunday==0, Monday==1, …, але й вводить перелічний тип з іменем week, який використовують у визначеннях та оголошеннях інших об’єктів.

Символьні (літерні) константи.

Це один чи два символи, обмежені апострофами. Односимвольні константи мають стандартний тип char. Для відтворення їх значень вводяться змінні символьного типу, тобто типу char. Приклади констант:‘z’,’*’,’\012’, ‘\0’, ‘\n’ – односимвольні константи. ‘db’, ‘\x07\x07’, ‘\n\t’ – двосимвольні константи.

Уваги заслуговують послідовності, що починаються знаком ‘\’.

Зображення

Внутрішній код

Позначення символа

Реакція чи суть

\a

0x07

Bel(audible bell)

Звуковий сигнал

\b

0x08

bs(backspace)

Повернення на крок (забій)

\f

0x0C

ff(form feed)

Переведення сторінки (форомату)

\n

0x0A

lf(line feed)

Переведення рядка (новий рядок)

\r

0x0D

cr (carriage return)

Повернення каретки

\t

0x09

ht (horizontal tab)

Табуляція горизонтальна

\v

0x0B

vt (vertical tab)

Табуляція вертикальна

\\

0x5C

\ (backslash)

Зворотна похила риска

\’

0x27

‘ (single quote)

Апостроф ( одинарна лапка)

\”

0x22

“ (double quote)

Подвійна лапка

\?

0x3F

? (question mark)

Знак запитання

\ooo

ooo

Довільний

Вісімковий код символа

\xhh

0xhh

Довільний

Шістнадцятковий код символла

Символ зворотної похилої риски ‘\’ використовується, по-перше, при запису кодів, що не мають графічного відтворення, і, по-друге, символів апостроф (‘), зворотна похила риска (\), знак запитання (?) та лапок (“). До того ж, зворотна похила риска дає змогу вводити символьні константи, вказуючи коди у вісімковій чи шістнадцятковій системі. Послідовність літер, що починається знаком ‘\’ , називають ескейп-послідовністю. Таблиця містить такі послідовності.

При потребі мати таблицю відповідності кодів та зображених на екрані символів у десятковому, вісімковому, шістнадцятковому відтворенні (кодів ASCII) використовують програму:

//Les2_3.CPP

#include

void main() {cout<< ‘\x0A’<<’\x48’<<’\x65’<<’\x6C’<<’\x6C;

cout<<’\x6F’<<’\x2C’; cout<<’\40’<<’\127’<<’\157’;

cout<<’\162’<<’\154’<<’\144’<<’\41’; }// Hello, World!

Два перші оператори виведення містять шістнадцяткові, а третій та четвертий – вісімкові коди символів:‘\x0A’–‘\n’;’\x48’-‘H’;…;’\40’-“пробіл”;’\127’ –‘W’;…; ’\41’- ‘!’.

Значенням символьної константи є числове значення її внутрішнього коду. У С++ односимвольна константа має тип char (1 байт), а двосимвольна - ‘\t\n’чи ‘\r\07’ відтворюється двобайтним значенням типу int, при цьому перший символ розташовується у молодшому байті ( з меншою адресою), а другий – у старшому байті. Названі узгодження показані у програмі:

//Les2_4.CPP

#include

void main() {cout<<”\n; cout<<”();”

cout<<”\nsizeof\’z\’=”<
cout<<”\nsizeof\’\\n\’=”<
cout<<”\nsizeof\’\\n\\t\’=”<
cout<<”\nsizeof\’\\x07\\x07\’=”<
cout<<”\nsizeof\’\\x0004F\’=”<
cout<<”\nsizeof\’\\x4F\’=”<
cout<<”\nsizeof\’\\111\’=”<
cout<<”\Десяткове значення”; cout<<”кода символа \’\\x4F\’=”<<(int)’\x4F’; // 79

cout<<”\nДесяткове значення ”;

cout<<”кода символа \’\\x4F\’=”<<(int)’\x4F’; // 79

cout<<”\nДесяткове значення кода пробілу =”; cout<<(int) ‘ ‘; // 32 }

Рядок або рядкова константа.

Вона визначається як послідовність символів, записана у лапках ( а не в апострофах). Наприклад: “Це рядок, що називається також рядковою константою”

Серед символів рядка можуть бути ескейп-послідовності, тобто сполуки, які відповідають символьним константам, що не мають відтворення на екрані монітора, або символам, що вказують їх внутрішні коди. У такому випадку, як і в попередніх відтвореннях окремих символів, вони починаються із зворотної похилої риски ‘\’.

//Les2_5.CPP

#include

void main() {cout<<”\nЦе рядок, \nінакше - \”стрінг \”, \nінакше - “;

cout<<“\”рядковий літерал \”.”;

При виведенні на екран монітора ескейп-послідовності ‘\n’ та ‘\”’ надрукують:

Це рядок

Інакше – “стрінг”

Інакше – “рядковий літерал”.

Наявність символа ‘\’ перед лапками у рядку дає змогу компілятору відокремити внутрішні лапки від обмежуючих рядок лапок. Рядки, записані у підряд чи через пробільні відокремлювачі, при компіляції конкатенуються, і послідовність:

“Рядок – це масив символів. “

“Рядок має тип char[].”

еквівалентна одному рядку: “Рядок – це масив символів. Рядок має тип char[].”

Довгу рядкову констанут можна ще одним способом розмістити у кількох рядках тексту програми, користуючись спеціальним позначенням переносу – ‘\’. Наприклад, одну рядкову константу можна записати на трьох рядках у тексті програми:

“Транслятор завжди відводить\

кожній рядковій константі\

окреме місце в па’яті ЕОМ.”

Наступна програма наводить різні способи “склеювання” рядків в один:

//Les2_6.CPP

#include

void main() {cout<<”\v1” “9” “93”

“рік”; // при виведенні пробіли видаляються

cout<<”почався з\

п’ятниці.”; } // Пробіли з цього рядка зберігаються

Результат виконання програми:

1993 рік почався з п’ятниці.

Важливо, що продовженням перенесеного за допомогою символа ‘\’ рядка вважається довільна інформація на наступному рядку, серед якої і пробіли.

Розташувавши рядок в пам’яті, транслятор автоматично додає в кінець символ ‘\0’, тобто нульовий байт. Тому кількість символів у внутрішньому відтворенні рядка на 1 більше від кількості символів його запису. Порожній рядок є одним символом “\0”.

Окрім безпосереднього використання рядків у виразах, рядок можна помістити у символьний (типу char) масив з вибраним іменем і пізніше звертатися до нього за іменем масиву. Найчастіше для розташування рядкової константи у масиві використовується його ініціювання. Наступна програма виконує вказані дії:

//Les2_7.CPP

#include

void main() {char radok[]=”Priklad vikoristannja inicijuvannja radka”; // 42

cout<<”nsizeof radok=”<
cout<<”\nradok=”<
Коли при визначенні масиву char після імені radok у дужках [] не вказана кількість елементів, тоді його розмір обчислюється автоматично при ініціюванні та дорівнює кількості символів у рядковій константі ініціювання плюс один елемент для завершального символа ‘\0’. Лапки не входять у рядок, а обмежують його при запису у програмі. У рядку може бути символ, наприклад “А” – це рядок з одного символа. Проте, на відміну від символьної константи ‘A’, довжина внутрішнього відтворення рядка “А” дорівнює 2. Рядок буває порожнім “”, тоді довжина дорівнює 1. Проте символьна константа не буває порожньою, тобто запис ‘’ у найчастіше не допустимий.

//Les2_8.CPP

#include

void main() {cout<<”\nsizeof\”\”=”<
cout<<”\tsizeof\’A\’=”<

cout<<”\nsizeof\’\\n\’=”<
cout<<”\tsizeof\’\\xFF\’=”<
cout<<”\tsizeof\”\\xFF\”=”<