
- •Передмова
- •Передмова до першого видання
- •Вступ
- •Вступний урок
- •Твердження for
- •Масиви
- •Аргументи - виклик за значенням
- •Типи, оператори та вирази
- •Константи
- •Оголошення
- •Оператори приросту та спаду
- •Оператори та вирази присвоєння
- •Вирази умов
- •Керування потоком
- •Вирази та блоки
- •If-else
- •Else if
- •Switch
- •Цикли while та for
- •Файли заголовка
- •Препроцесор C
- •Покажчики та масиви
- •Покажчики й адреси
- •Покажчики та масиви
- •Арифметика адрес
- •Аргументи командного рядка
- •Структури
- •Масиви структур
- •Покажчики на структури
- •Typedef
- •Сполуки
- •Ungetc
- •Виконання команд
- •Генератор випадкових чисел
- •Open, creat, close, unlink
Роздiл 2
Типи, оператори та вирази
Змiннi та сталi — це основнi об’єкти даних, якими орудує програма. Оголошення укладають список змiнних, що використовуватимуться, i зазначають їхнiй тип i, можливо, початкове значення. Оператори вказують на виконувану дiю. Вирази об’єднують змiннi та сталi для утворення нового значення. Тип певного об’єкту обумовлює набiр значень, який той може мати, а також, якi саме операцiї застосовнi щодо нього. Цi складовi частини i є темою даного роздiлу.
Стандарт ANSI привнiс багато малих змiн i доповнень до основних типiв i виразiв. Тепер iснують знаковi (signed) та беззнаковi (unsigned) форми всiх типiв цiлих, а також позначення для беззнакових констант i шiстнадцяткових символьних констант. Операцiї з рухомою точкою можливi з одинарною точнiстю; iснує також тип long double (довге подвiйне число) для пiдвищеної точностi. Ланцюжковi константи може бути зчеплено пiд час компiляцiї. Перелiки (енумерацiя) стали офiцiйною частиною мови, формалiзуючи цю довготривалу рису. Об’єкти можна оголосити як const, що запобiгає їхнiй змiнi. Доповнено правила автоматичного коригування серед арифметичних типiв, для можливостi оперування багатшим набором.
2.1Назви змiнних
Хоч ми не згадали про це в Роздiлi 1, iснують певнi обмеження щодо назв змiнних та символiчних констант. Назви повиннi складатися з лiтер i цифр, першим знаком має бути лiтера. Жорсткий пробiл _ теж вважається лiтерою, вiн часом корисний для покращення прочитностi довгих назв змiнних. Однак, не починайте назв змiнних з жорсткого пробiлу, оскiльки функцiї бiблiотеки часто використовують такi назви для власних потреб. Лiтери верхнього регiстру та лiтери нижнього регiстру рiзняться, тож x та X — це двi рiзнi назви. Традицiйною практикою в C є використання лiтер нижнього регiстру для назв змiнних i тiльки верхнього для символiчних констант.
Щонайменше, 31 знак внутрiшнього iменi є значущим. Для назв функцiй i зовнiшнiх змiнних число може виявитися меншим за 31, оскiльки зовнiшнi назви можуть використовуватись асемблерами та завантажувачами зв’язкiв, над якими мова не має
37
38 |
РОЗДIЛ 2. ТИПИ, ОПЕРАТОРИ ТА ВИРАЗИ |
жодного впливу. Для зовнiшнiх iмен, стандарт гарантує унiкальнiсть тiльки для 6-ох знакiв одного регiстру. Ключовi слова, такi як if, else, int, float тощо, зарезервовано — ви не можете використати їх для назв змiнних. Ключовi слова мають бути нижнього регiстру.
Розумним буде обирати такi назви змiнних, якi би вiдображали змiст змiнної i якi неможливо би було типографiчно сплутати з iншими. Ми схильнi вживати короткi назви для локальних змiнних, особливо лiчильникiв циклу, i довшi — для зовнiшнiх змiнних.
2.2Типи даних i розмiри
Iснує лише кiлька основних типiв даних у C:
char один байт, здатний утримувати один знак локального набору символiв
int цiле, типово вiдображає натуральний розмiр цiлих машини float одинарної точностi число з рухомою точкою
double подвiйної точностi число з рухомою точкою
На додачу, iснує певна кiлькiсть класифiкаторiв, якi можна використати стосовно вищевказаних основних типiв. Так, short iз long застосовуються з цiлими:
short int sh; long int counter;
Слово int можна опустити в таких оголошеннях i, типово, саме так i роблять. Iдея полягає в тому, що short та long мають забезпечувати рiзними довжинами
цiлих, там де це має практичний сенс; int, як правило, буде натуральним розмiром цiлого для певної машини. short часто має 16-бiтну довжину, а int — 16, або 32-бiтну. Кожний компiлятор може вибрати вiдповiднi розмiри для власного устаткування, єдиним обмеженням будучи те, що short та int повиннi мати щонайменше 16 бiт, long — 32 бiти, short не може бути довшим за int, який, в свою чергу — не довшим за long.
Класифiкатори signed або unsigned можна застосовувати щодо char або будьякого цiлого. Беззнаковi, unsigned, числа завжди додатнi або нуль i пiдлягають правилам арифметичного модуля 2 , де n — це кiлькiсть бiтiв використаного типу. Тож, наприклад, якщо char має довжину 8 бiтiв, змiннi типу unsigned char матимуть значення мiж 0 та 255, тодi як signed char — мiж -128 та 127 (в машинi з двiйковою системою). Чи звичайнi char вживаються зi знаком, чи є беззнаковими, залежить вiд машини, але друковнi знаки завжди додатнi.
Тип long double вказує на число з рухомою точкою пiдвищеної точностi. Так само, як i у випадку з цiлими, розмiри об’єктiв з рухомою точкою залежать вiд реалiзацiї; float, double i long double можуть представляти один, два або три вiдмiнних розмiри.
2.3. КОНСТАНТИ |
39 |
Стандартнi файли заголовка <limits.h> i <float.h> мiстять символiчнi константи для всiх трьох розмiрiв, разом iз iншими властивостями машини та компiлятора. Це все розглянуто у Додатку Б.
Вправа 2-1. Напишiть програму для визначення амплiтуд змiнних char, short, int i long, як зi знаком, singned, так i беззнакових, unsigned, шляхом виводу вiдповiдних значень з файлiв заголовка i шляхом безпосереднього обчислення. Важче, якщо ви обчислите їх. Визначте дiапазон рiзноманiтних типiв з рухомою точкою.
2.3Константи
Цiлочисельна константа, наприклад 1234, має тип int. Довга константа пишеться з кiнцевою l (англiйська ел ) або L, як от 123456789L; цiлочисельна константа, занадто велика для того, щоб умiститися в int, також буде розглянута як long. Беззнаковi константи пишуться з кiнцевою u (англiйська ю ) або U, а суфiкс ul або UL вказує на тип unsigned long (беззнакове довге цiле).
Константи з рухомою точкою, повиннi мiстити або десяткову крапку, або експоненту, або обидвi; їхнiй тип вважається double, хiба що вказано якийсь iнший суфiкс. Суфiкс f або F позначає константу з рухомою точкою, float; l або L вказують на long double (довге подвiйне число з рухомою точкою).
Значення цiлого можна вказати як вiсiмкове або шiстнадцяткове, замiсть десяткового. Переднiй 0 (нуль), у випадку цiлої константи, означає вiсiмкове число; 0x або 0X попереду означають шiстнадцяткове. Так, наприклад, десяткове 31 може бути записано як 037 у вiсiмковiй системi, i 0x1f або 0x1F — у шiстнадцятковiй. За вiсiмковими та шiстнадцятковими константами може також слiдувати L, щоб помiняти їхнiй тип на long, або U, щоб перетворити їх на беззнаковi; 0XFUL — це константа, яка має тип unsigned long (беззнакова довга) iз десятковим значенням 15.
Символьна константа — це цiле, записане як символ в одинарних лапках, як от ’x’. Значення символьної константи дорiвнює числовому значенню знака в наборi знакiв машини. Наприклад, у наборi знакiв ASCII, символьна константа ’0’ має значення 48, що не має жодного стосунку до числового значення 0. Якщо ми напишемо ’0’, замiсть числового значення 48, яке залежить вiд набору знакiв, програму, що не залежатиме вiд певного числового значення, буде водночас легше читати. Символьнi константи можуть брати участь у числових операцiях так само, як i iншi цiлi, хоч їх частiше використовують для порiвнянь з iншими знаками.
Деякi знаки в символьних i ланцюжкових константах можна представити як екранованi послiдовностi, наприклад n (знак нового рядка); цi послiдовностi виглядають як два знаки, але означають тiльки один. На додаток, довiльний ряд бiтiв розмiром один байт можна вказати як
’\ooo’
де ooo — це одна до трьох вiсiмкових цифр (0. . . 7), або як
40 |
РОЗДIЛ 2. ТИПИ, ОПЕРАТОРИ ТА ВИРАЗИ |
’\xhh’
де hh — це одна або бiльше шiстнадцяткових цифр (0...9, a...f, A...F). Таким чином, ми можемо написати
#define VTAB ’\013’ /* вертикальна табуляцiя в ASCII */ #define BELL ’\007’ /* символ дзвоника в ASCII */
або в шiстнадцятковiй формi |
|
|
#define VTAB ’\xb’ |
/* вертикальна табуляцiя в |
ASCII */ |
#define BELL ’\x7’ |
/* символ дзвоника в ASCII |
*/ |
Ось повний набiр екранованих послiдовностей: a символ сигналу (дзвоника) зворотня похила b реверс (крок назад) ? знак питання f змiна сторiнки ’ одинарнi лапки n новий рядок ¨ подвiйнi лапки r повернення каретки ooo вiсiмкове числоt горизонтальна табуляцiя x hh шiстнадцяткове число v вертикальна табуляцiя
Символьна константа ’ 0’ позначає знак зi значенням нуль, нульовий знак. ’ 0’ часто використовується замiсть 0, щоб пiдкреслити символьне походження деяких виразiв, але числове значення — це просто 0.
Сталий (константний) вираз — це такий, що включає тiльки сталi (константи). Такi вирази оцiнюються пiд час компiляцiї, а не пiд час обiгу програми i, вiдповiдно, можуть використовуватись у будь-якому мiсцi, де може стояти константа, скажiмо
#define MAXLINE 1000 char line[MAXLINE+1];
або
#define LEAP 1 /* високосний рiк */
int days[31+28+LEAP+31+30+31+30+31+31+30+31+30+31];
Ланцюжкова константа, або ланцюжковий лiтерал — це послiдовнiсть iз нуля або бiльше знакiв, оточених подвiйними лапками, як, наприклад
"I am a string"
або
"" /* порожнiй ланцюжок */
2.3. КОНСТАНТИ |
41 |
Лапки не є частиною ланцюжка, а служать лише для його обмеження. Тi самi екранованi послiдовностi, якi використовуються в символьних константах, можна так само застосувати в ланцюжках; ¨ представляє знак подвiйних лапок. Ланцюжковi константи можна зчепити пiд час компiляцiї:
"hello, " "world"
тотожно
"hello, world"
Це зручно для подiлу довгих ланцюжкiв на декiлька рядкiв вихiдного тексту. Технiчно, ланцюжкова константа — це масив знакiв. Внутрiшнє представлення лан-
цюжка включає нульовий знак ’ 0’ укiнцi, тож фiзичне мiсце зберiгання вимагає на один бiльше символiв, нiж тi, що знаходяться в подвiйних лапках. Цей спосiб подання означає, що не iснує обмеження довжини ланцюжка, але програми повнiстю має просканувати ланцюжок, щоб визначити його довжину. Функцiя стандартної бiблiотеки strlen(s) повертає довжину свого аргументу, символьного ланцюжка s, за виключенням кiнцевого ’ 0’. Ось наша версiя цiєї функцiї:
/* strlen: повертає довжину s */
int strlen(char s[])
{
int i;
while (s[i] != ’\0’) ++i;
return i;
}
strlen та iншi ланцюжковi функцiї оголошено у стандартному файлi заголовка
<string.h>.
Будьте обережнi, щоб зумiти вiдрiзнити символьну константу вiд ланцюжка, який мiстить один знак: ’x’ — це не те саме, що x . Перше — це цiле число, яке використовується для здобуття числового значення лiтери x у машинному наборi символiв. Друге — масив символiв, який мiстить єдиний знак (лiтеру x) i ’ 0’.
Iснує ще один вид сталих — константи перелiку. Перелiк — це список сталих цiлих значень, наприклад
enum boolean { NO, YES };