Константи, C початківцю, C
Константи з Плаваючою Точкою
C++ дає можливість записування значень основних типів: символьних констант, цілих констант і констант з плаваючою точкою. Крім того, нуль (0) може використовуватися як константа будь-якого вказівного типу і символьні рядки є константами типу char[]. Також можна задавати символічні константи. Символічна константа - це ім'я, значення якого може бути змінено у його області видимості. У C++ є три види символічних констант:
будь-якому значенню будь-якого типу можна дати ім'я та використовувати його як константу, додавши до його опису ключове слово const;
безліч цілих констант можна визначити як перерахування;
будь-яке ім'я вектора чи функції є константою.
Цілі константи постають у чотирьох обличчях: десяткові, вісімкові, шістнадцяткові та символьні константи. Десятні використовуються найчастіше і виглядають так, як можна було б очікувати:
| 0 | 1234 | 976 | 12345678901234567890 |
Десяткова константа має тип int, за умови, що вона влазить у int, інакше її тип long. Компілятор повинен попереджати про константів, які надто довгі для подання у машині.
Константа, яка починається банкрутом за яким йде x (0x), є шістнадцятковим числом (з основою 16), а константа, яка починається банкрутом за яким йде цифра, є вісімковим числом (з основою 8). Ось приклади вісімкових констант:
| 0 | 02 | 077 | 0123 |
їх десяткові еквіваленти - це 0, 2, 63, 83. У шістнадцятковому записі ці константи виглядають так:
| 0x0 | 0x2 | 0x3f | 0x53 |
Літери a, b, c, d, e та f, або їх еквіваленти у верхньому регістрі, використовуються для представлення чисел 10, 11. 12, 13, 14 та 15 відповідно. Восьмерична та шістнадцяткова записи найбільш корисні для запису набору бітів; застосування цих записів для вираження звичайних чисел може призвести до несподіванок. Наприклад, на машині, де int представляється як двійкове додаткове шістнадцяткове ціле, 0xffff є негативним десятковим числом -1; якби для уявлення цілого використовувалося більше бітів, воно було б числом 65535.
Константи з Плаваючою Точкою
Константи з плаваючою точкою мають тип double. Як і в попередньому випадку, компілятор повинен попереджати про константів з плаваючою точкою, які занадто великі, щоб їх можна було уявити. Ось деякі константи з плаваючою точкою:
1.23 .23 0.23 1. 1.0 1.2e10 1.23e-15
Зауважте, що всередині константи з плаваючою точкою не може зустрічатися пробіл. Наприклад, 65.43 e-21 не є константою з плаваючою точкою, а чотирма окремими лексичними символами (лексемами):
та викличе синтаксичну помилку. Якщо ви хочете мати константу з плаваючою точкою типу float, ви можете визначити її так:
const float pi=3.14159265;
Хоча в C++ немає окремого символьного типу даних, точніше, символ може зберігатися загалом типі, у ньому для символів є спеціальна і зручна запис. Символьна константа – це символ, укладений у одинарні лапки; наприклад, "a" або "0". Такі символьні константи є символічними константами для цілого значення символів у наборі символів тієї машини, на якій буде виконуватися програма (який не обов'язково збігається з набором символів, що застосовується)тому комп'ютері, де програма компілюється). Тому, якщо ви виконуєтеся на машині, що використовує набір символів ASCII, то значенням "0" буде 48, але якщо ваша машина використовує EBCDIC, то воно буде 240. Вживання символьних констант замість десяткового запису робить програму більш переносимою. Декілька символів також мають стандартні імена, в яких зворотна коса \ використовується як escape-символ:
| "\b" | повернення назад |
| "\f" | переклад формату |
| "\n" | новий рядок |
| "r" | повернення каретки |
| "\t" | горизонтальна табуляція |
| "\v" | вертикальна табуляція |
| "\" | зворотна коса (зворотний слеш) |
| "\" | одинарна лапка |
| "\" | подвійна лапка |
| "\0" | null, порожній символ, значення 0 |
Всупереч їхньому зовнішньому вигляду кожне є одним символом. Можна також представляти символ одно-, дво- чи тризначним вісімковим числом (символ \, за яким йдуть вісімкові цифри), або одно-, дво- або трицифровим шістнадцятковим числом (\x, за яким йдуть шістнадцяткові цифри). Наприклад:
"\6" "\x6" 6 ASCII ack "\60" "\x30" 48 ASCII "0" "\137" "\x05f" 95 ASCII "_"
Це дозволяє подавати кожен символ із машинного набору символів, і зокрема вставляти такі символи у символьні рядки . Застосування цифрового запису для символів робить програму непереносною між машинами з різними наборами символів.
Рядкова константа - це послідовність символів, укладена в подвійні лапки:
Кожна рядкова константа містить один символ більше, ніж здається; всі вони закінчуються порожнімсимволом \0 зі значенням 0.
Рядок має тип "вектор із відповідного числа символів", тому "asdf" має тип char[5]. Порожній рядок записується "" (та має тип char[1]). Зауважте, що для кожного рядка s strlen(s)==sizeof(s)-1, оскільки strlen() не враховує завершальний 0. Угода про подання неграфічних символів зі зворотною косою можна використовувати також і всередині рядка. Це дає можливість представляти у рядку подвійні лапки та escape-символ. Звичайним символом цього роду є, безумовно, символ нового рядка "\n".
де 7 – значення ASKII символу bel (дзвінок).
У рядку неможливо мати "справжній" новий рядок:
"це не рядок, а синтаксична помилка"
Однак у рядку може стояти зворотна коса, відразу після якої йде новий рядок; і те, й інше буде проігноровано.
Новий рядок, перед яким йде escape (зворотний косий), не призводить до появи в рядку нового рядка, це просто домовленість про запис.
У рядку можна мати порожній символ, але більшість програм не припускатимуть, що є символи після нього. Наприклад, рядок "asdf\000hjkl" розглядатиметься стандартними функціями, на кшталт strcpy() і strlen(), як "asdf".
Вставляючи чисельну константу в рядок за допомогою восьмеричного або шістнадцяткового запису розумно завжди використовувати число з трьох цифр. Читати запис досить важко і без необхідності турбуватися про те, чи символ після константи цифрою чи ні. Розберіть ці приклади:
char v1[] = "a\x0fah\0129"; // "a" "\xfa" "h" "\12" "9" char v2[] = "a\xfah\129"; // "a" "\xfa" "h" "\12" "9" char v3[] = "a\xfad\127"; // "a" "\xfad" "\127"
Майте на увазі, що двозначний шістнадцятковий запис на машинах з 9-бітовимбайтом буде недостатньо.
Ключове слово const може додаватися до опису об'єкта, щоб зробити цей об'єкт константою, а не змінною.
const int model = 145; const int v[] = < 1, 2, 3, 4 >;
Оскільки константі нічого не можна привласнити, вона має бути ініціалізована. Опис чогось як const гарантує, що його значення не зміниться в області видимості:
модель = 145; // помилка model++; // помилка
Зверніть увагу, що const змінює тип, тобто обмежує спосіб використання об'єкта, замість того, щоб задавати спосіб розміщення константи. Тому, наприклад, цілком розумно, а іноді й корисно, описувати функцію як повертаючу const:
const char* peek(int i) return private[i]; >
З іншого боку, компілятор може декількома шляхами скористатися тим, що об'єкт є константою (звісно, залежно від того, наскільки він розумний). Найочевидніше - те, що константи не потрібно виділяти пам'ять, оскільки компілятор знає її значення. Крім того, ініціалізатор константи часто (але не завжди) є константним виразом, тобто може бути обчислений на стадії компіляції. Однак для вектора констант зазвичай доводиться виділяти пам'ять, оскільки компілятор у загальному випадку не може обчислити, які елементи вектора зроблені посилання у виразах. Однак на багатьох машинах навіть у цьому випадку може досягатися підвищення ефективності шляхом розміщення векторів констант на згадку, доступну тільки для читання.
Використання покажчика залучає два об'єкти: сам покажчик і об'єкт, що вказується. Постачання опису покажчика "префіксом" const робить об'єкт, але не сам покажчик, константою.
const char * pc = "asdf"; // покажчик наконстанту pc[3] = "a"; // помилка
pc = "ghjk"; // ok
Щоб описати сам покажчик, а не об'єкт, що вказується, як константний, використовується операція const*.
char * const cp = "asdf"; // Константний покажчик cp [3] = "a"; // ok cp = "ghjk"; // помилка
Щоб зробити константами обидва об'єкти, їх обидва потрібно описати const.
const char * const cpc = "asdf"; // const покажчик на const cpc [3] = "a"; // помилка cpc = "ghjk"; // помилка
Об'єкт, що є константою при доступі до нього через один покажчик, може бути змінною, коли доступ здійснюється іншими шляхами. Це, зокрема, корисно для параметрів функції. За допомогою опису параметра покажчика як const функції забороняється змінювати об'єкт, який він вказує.
char * strcpy (char * p, const char * q); // не може змінити q
int a = 1; const c = 2; const* p1 = &c; // ok const * p2 = &a; // ok int* p3 = &c; // Помилка * p3 = 7; // змінює значення c
Як завжди, якщо тип в описі опущений, він передбачається int.
Є інший метод визначення цілих констант, який іноді зручніший, ніж застосування const.
визначає три цілих константи, які називають перелічниками, і присвоює їм значення. Оскільки значення перелічників за замовчуванням надаються починаючи з 0 у порядку зростання, це еквівалентно запису:
const ASM = 0; const AUTO = 1; const BREAK = 2;
Перелік може бути іменованим.
Ім'я перерахування стає синонімом int, а чи не новим типом. Опис змінної keyword, а чи не просто int, може дати як програмісту, і компілятору підказку у тому, що використання навмисне.
keyword key; switch (key) case ASM: // щосьробить break; case BREAK: // щось робить break; >
спонукає компілятор видати попередження, оскільки тільки два значення keyword з трьох використовуються.
Також можна задавати значення перелічників явно.
enum int16 sign=0100000, // знак most_significant=040000, // найзначніший least_significant=1 // найменш значущий >;
Такі значення не обов'язково мають бути різними, зростаючими чи позитивними.