ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 21.12.2021
Просмотров: 975
Скачиваний: 3
Найбільш частіше використовуються такі директиви препроцесора:
- #include ( включає файл у текст програми );
- #define ( замінює ідентифікатор на літерал ).
Директива #include має два формати:
1. #include "ім'я_файлу".
2. #include <ім'я_файлу>.
Якщо ім'я файла вказане в лапках, то його пошук здійснюється в поточному каталозі користувача. Якщо ім'я файла задане в кутових дужках, то його пошук проводиться в стандартних директоріях операційної системи, наприклад, для компілятора DevC++ це «C:\Dev-C++\Include\».
Приклад 8. Синтаксис бібліотек
# include <stdio.h> /* підключення стандартної бібліотеки введення-виведення stdio.h */
# include <stdlib.h> /* підключення стандартної бібліотеки stdlib.h */
# include «myfync.h» /*підключення файлу користувача myfync.h */
Формат директиви # define:
# define стрічка_1 стрічка_2
де стрічка_1 – ідентифікатор, стрічка_2 – літерал.
Директива #define замінить всі появи ідентифікатора "стрічка_1" у вихідному файлі на літерал «стрічка_2». Заміна ідентифікатора буде здійснена тільки тоді, коли він формує лексему. Наприклад, ідентифікатор «стрічка_1» не буде замінений, якщо він присутній у стрічковому літералі чи є частиною довшого ідентифікатора.
Приклад 9. Запис Директиви #define
# define SIZE 12 /* У тексті програмі всі лексеми SIZE будуть замінені на цілий літерал 12. */
Варто відмітити що при використанні # define немає необхідності у використанні оператора «;» .
Файли заголовків мають розширення ".h", а файли коду — розширення ".с" або ".срр".
Файли коду містять реалізацію програми користувача і мають розширення ".с" або ".срр". Вони складаються з однієї або більше функцій. Одна з функцій, з яких починається виконання програми, повинна мати ім'я main. Функція main відрізняється від інших функцій тим, що її не можна викликати зсередини програми, а її параметри задаються операційною системою. Параметри у функції main можуть бути відсутні.
Виклик функції (активізація) виконується двома способами: класичним — за іменем; побічно — через покажчик на функцію (див. тему "Покажчики"). Класичний спосіб виклику функції проводиться за допомогою вказівки імені в дужках, за яким указується список параметрів (аргументів). Список параметрів являє собою значення (змінних, констант, покажчиків констант або адрес), які необхідно передати функції для успішного розв'язання задачі. Функція активізується завжди, коли в керуючій програмі зустрічається ім'я функції.
Після виконання відповідної функції управління передається назад у середовище програми (за винятком особливих ситуацій), яка продовжує свою роботу.
3.10 Організація програми
Програма на мові С складається з файлів двох типів – файлів заголовків і файлів коду. Файли заголовків мають розширення ".h", а файли коду – розширення ".с".
Програма мовою C складається із файлів двох типів – файлів заголовків і файлів коду. Файли заголовків мають розширення ".h", а файли коду – розширення ".с" або ".срр". Файли заголовків містять класи, шаблони, структури, об'єднання, перерахування, оголошення функцій, описи typedef, визначення констант, функції inline і директиви препроцесора.
При компіляції оголошення заголовкових файлів включаються в будь-який файл, де використовуються зовнішні функції, класи й об'єкти, що містяться в ньому. Заголовкові файли включаються за допомогою директиви препроцесора #include, що має дві форми:
^include "ім'я заголовкового файла" #include <ім' я заголовкового файла>
Якщо ім'я заголовкового файла вказане в лапках, то його пошук здійснюється в поточному каталозі користувача. Якщо ім'я файла задане в кутових дужках, то його пошук провадиться в стандартних директоріях операційної системи.
Файли коду містять реалізацію програми користувача і мають розширення ".с" або ".срр". Вони складаються з однієї або більше функцій. Одна з функцій, з яких починається виконання програми, повинна мати ім'я main. Функція main відрізняється від інших функцій тим, що її не можна викликати зсередини програми, а її параметри задаються операційною системою. Параметри у функції main можуть бути відсутні. Виклик функції (активізація) виконується двома способами: класичним — за іменем; побічно — через покажчик на функцію (див. тему "Покажчики"). Класичний спосіб виклику функції проводиться за допомогою вказівки імені в дужках, за яким указується список параметрів (аргументів). Список параметрів являє собою значення (змінних, констант, покажчиків констант або адрес), які необхідно передати функції для успішного розв'язання задачі. Функція активізується завжди, коли в керуючій програмі зустрічається ім'я функції. Після виконання відповідної функції управління передається назад у середовище програми (за винятком особливих ситуацій), яка продовжує свою роботу.
КОНТРОЛЬНІ ЗАПИТАННЯ
-
Що таке алфавіт мови програмування?
-
Яка важлива відмінність мови С пов’язана з алфавітом?
-
Що таке лексема?
-
Що таке ключові слова?
-
Наведіть приклад деяких ключових слів.
-
Що таке ідентифікатор?
-
Що таке тип даних?
-
Які існують категорії типів даних?
-
Наведіть класифікацію типів даних.
-
Охарактеризуйте тип void.
-
Що таке літерал?
-
Які існують види літералів?
-
Які ескейп-послідовності ви знаєте?
-
Який розмір має літерал “abcd”? (5 байт)
-
Опишіть формат дійсного літералу.
-
Що таке оператор?
-
Чим відрізняються оператори (охарактеризуйте кожен з них)?
-
Що таке коментар?
-
Для чого потрібні коментарі?
-
Що таке препроцесор?
-
Що таке директива препроцесора?
-
Які директиви найчастіше використовуються?
-
Опишіть формат директиви #define.
-
З яких файлів складається програма мови С?
3. ОПЕРАЦІЇ ТА ВИРАЗИ
4.1 Загальні відомості
Комбінація знаків операцій і операндів, результатом якої є певне значення, називається виразом.
Операнд – це те, над чим виконуються операції. У мові С у якості операндів можуть виступати літерали, змінні, елементи масиву, результати визову функції, вирази. Будь-який операнд, що має константне значення, називається константним виразом. Кожен операнд має тип.
Знаки операцій визначають дії, що повинні бути виконані над операндами. Кожен операнд у виразі може бути виразом. Значення виразу залежить від розташування знаків операцій і круглих дужок у виразі, а також від пріоритету виконання операцій. Пріоритет виконання операцій представлений у таблиці 4.1.
Таблиця 4.1 – Пріоритет виконання операцій
Пріоритет |
Операція |
Типи операції |
Порядок виконання |
1 |
() [] . |
Вираз |
Зліва направо |
2 |
->- ~ ! * & ++ -- sizeof |
Унарні |
Справа на ліво |
3 |
приведення типу () |
Унарний |
Справа на ліво |
4 |
* / % |
Мультиплікативні |
Зліва направо |
5 |
+ - |
Адитивні |
|
6 |
<< >> |
Зсув |
|
7 |
< > <= >= |
Відношення |
|
8 |
== != |
Відношення (рівність) |
|
9 |
& |
Порозрядне «І» |
|
10 |
^ |
Порозрядне виключне «АБО» |
|
11 |
| |
Порозрядне «АБО» |
|
12 |
&& |
Логічне «І» |
|
13 |
|| |
Логічне «АБО» |
|
14 |
?: |
Умовна |
|
15 |
= *= /= %= += -= &= |= >>= <<= ^= |
Просте і складене присвоєння |
Справа на ліво |
16 |
, |
Послідовне обчислення |
Зліва на право |
Приклад 1. Приорітет операцій
int a=2, b=3, c=4, d=7, e, f;
e = a + b/c + d & a * b - d % a; /*e = 1*/
Порядок виконання операцій у виразі визначається пріоритетом операцій, для прикладу 4.1 зображений на рис. 4.1.
Рисунок 4.1 – Порядок виконання операцій у виразі
Спочатку буде виконані операції з найвищим пріоритетом, тобто b/c (3/4 = 0) , a*b (2*3 = 6) та d%a (7%2 = 1). Вираз можна переписати, як:
e = a + 0 + d & 6 - 1;
Наступними виконаються адитивні операції a + 0 + d (2+0+7 = 9) та 6 - 1 (=5) і вираз можна переписати як:
e = 9 & 5;
Наступною виконається операція порозрядного «І» 9 & 5 (=1) і останньою операція присвоювання e = 1, в результаті якої змінна e буде містити число 1.
Так як операція «()» має найвищий пріоритет для зміни пріоритету частини виразу, його можна взяти у дужки, таким чином ця частина виразу виконається впершу чергу. У випадку вкладених дужок в першу чергу виконається вираз у внутрішніх дужках.
Приклад 2. Приорітет операцій
int a = 2, b = 3, c = 4, d;
d = a + b * c; /* спочатку виконається вираз b * c, потім результат цього виразу буде доданий до a, тобто d = 14 */
d = (a + b) * c; /*спочатку виконається вираз a + b, потім результат цього виразу буде помножений на с, тобто d = 20 */
4.2 Арифметичні операції
До арифметичних операцій відносяться операції додавання (+), віднімання (-), множення (*), ділення (/) і визначення залишку від ділення (%).
Типи операндів арифметичних операцій, крім операції (%), можуть відрізнятися, і для них справедливі правила перетворення типів. Операндами операції (%) повинні бути цілі числа. Типом результату є тип операндів після перетворення.
Відомості про арифметичні операції зведені в таблиці.
Таблиця 4.2– Арифметичні операції
Дія |
Арифметична операція |
Алгебраїчний вираз |
Вираз мовою С |
Додавання |
+ |
t + 9 |
t + 9 |
Віднімання |
- |
r – f |
r – f |
Множення |
* |
ab |
a * b |
Ділення |
/ |
x/y чи x:y чи |
x / y |
Залишок від ділення |
% |
z mod w |
z % w |
Як видно з таблиці арифметичні вирази мовою С записуються в стрічку, так як в такому вигляді легче ввести програму в комп’ютер.
Операція множення (*) виконує множення операндів.
Приклад 3. Множення операндів
int k=5;
float f=0.2;
double g;
g=f*k;
Тип добутку f й k перетвориться до типу double, потім результат присвоюється змінній g.
Операція ділення (/) виконує ділення першого операнда на другий. Якщо ділене і дільник цілі, то за наявності залишку він відкидається. При спробі ділення на нуль видається повідомлення про помилку під час виконання.
Приклад 4. Операція ділення.
int a = 7, b = 5, c = 0, d;
d = a/b; /* d = 1, залишок відкинуто */
d = b/a; /* d = 0, залишок відкинуто */
Операція (%) – визначає залишок від ділення першого операнда на другий. Знак результату залежить від конкретної реалізації. Якщо другий операнд дорівнює нулю, то видається повідомлення про помилку.
Приклад 5. Визначення лишка від ділення операндів
int a = 7, b = 5, c = 0, d;
d = a % b; /* d = 2 – залишок від цілого поділу 7/5. */
d = b % a; /* d = 5 – залишок від цілого поділу 5/7. */
d = b % c; /* повідомлення про помилку */
4.3 Операції приведення типів
У виразах мовою С допускається використання операндів різних типів. При обчисленні виразу тип кожного операнда може бути перетворений до іншого типу. Перетворення типів можуть бути неявними, при виконанні операцій і викликів функцій, чи явними, при виконанні операцій приведення типів.
Неявне перетворення здійснюється автоматично для приведення операндів виразів до загального типу чи для розширення коротких величин до розміру цілих величин, використовуваних у машинних командах. Виконання перетворення залежить від специфіки операцій і від типу операнда чи операндів. Існує загальне правило: при обчисленні виразів операнди перетворяться до типу того операнда, що має найбільший розмір.
У процесі обчислення виразу операнди різних типів приводяться до єдиного за таким правилом:
- будь-яке char, short або enum перетворяться в int або unsigned;
- якщо після першого кроку протиріччя в розходженні типів не усунені, то відбувається додаткове перетворення типів операндів відповідно до ієрархії типів:
int<unsigned<long< unsigned long<float<double<long double.
Оператор явного перетворення типу має вигляд:
(тип) ідентифікатор,
де тип – визначає тип даних до якого здійснюється перетворення.
Приклад 6. Операція приведення типів
double f;
int a=2, b=3;
f=a/b; /* f=0 */
f=(double)a/b; /* f=0,66666 */
В останньому виразі перед операцією ділення виконується операція перетворення типу змінної а. Спочатку а=2, а при явному перетворенні а=2.0. Тепер перший операнд (a) став типу double, а другий (b), типу int. Раніше говорилося про те, що перед виконанням операції обидва операнда приводяться до одного типу. При цьому тип, який має більш низький пріоритет, перетворюється до типу з пріоритетом більш високим. Тобто int перетворюється у double. Потім виконується ділення, в результаті якого f=0,66666.
4.4 Операції присвоєння
Операція простого присвоєння використовується для заміни значення лівого операнда, значенням правого операнда. При присвоюванні відбувається перетворення типу правого операнда до типу лівого операнда.
Приклад 7. Операція простого присвоєння
int t;
char f ='a';
long z = 10;
t = f + z; /*t = 107*/
Значення змінної f перетворюється до типу long, обчислюється вираз f+z, результат перетворюється до типу int і потім присвоюється змінній t.
Крім простого присвоєння, є ціла група операцій присвоєння, що поєднують просте присвоєння з однією з бінарних операцій. Такі операції називаються складеними операціями присвоєння і мають вигляд:
(операнд-1) (бінарна операція) = (операнд-2) .
Складене присвоєння по результату еквівалентно наступному простому присвоєнню:
(операнд-1) = (операнд-1) (бінарна операція) (операнд-2) .
Кожна операція складеного присвоєння виконує перетворення, що здійснюються відповідною бінарною операцією.
Відомості про складені операції присвоювання представлені у табл.
Таблиця 4.3 – Складені операції присвоювання
Лексема |
Пояснення складеної операції присвоєння |
*= |
помножити та присвоїти |
/= |
поділити та присвоїти |
%= |
залишок від ділення та присвоїти |
+= |
додати та присвоїти |
-= |
відняти та присвоїти |
&= |
порозрядне логічне «І» та присвоїти |
|= |
порозрядне логічне «АБО» та присвоїти |
>>= |
зсув вправо та присвоїти |
<<= |
зсув вліво та присвоїти |
^= |
порозрядне логічне «виключне АБО» та присвоїти |
Приклад 8. Види арифметичних операцій
int a = 1, b = 3, c = 6, d = 16, e = 9;
a+=2; /*еквівалентно виразу a = a + 2; */
b-=c; /* еквівалентно виразу b = b - c;*/
c/=3; /*еквівалентно виразу c = c / 3; */
d>>=4; /*еквівалентно виразу d = d >> 4; */
e%=a; /* еквівалентно виразу e = e % a;*/
4.5 Операції інкремента і декремента
Операції інкремента (++) і декремента (--) є унарними операціями присвоєння. Ці операції відповідно збільшують чи зменшують значення операнда на одиницю. Операнд може бути цілого чи дійсного типу чи бути покажчиком.
Операції інкремента і декремента мають дві форми запису: префіксна, коли операнд розташовується після знака операції (наприклад, ++а, --а); постфіксна, коли операнд розташовується ліворуч від знака операції (наприклад, а++, а--).