M_CI_1
.pdf
F. Константа 3.1457F має довжину типу float. Використовуючи букви L або l, одержимо зна-
чення типу long double.

Приклад 1.7:
1:#include <stdio.h>
2:#include <stdlib.h>
4:main()
5:{
6:double list, paid, rate, tax;
7:char s[20];
8:
9:printf(”Заплачена ціна?\n”);
10:scanf(”%20s”,s);
11:paid = atof(s); /*функція із <stdlib.h> для перетворення рядка в числове
12: |
значення з плаваючою крапкою */ |
13:printf(“Ставка податку ( наприклад: 0.2)? ”);
14:scanf(”%20s”,s);
15:rate = atof(s);
16:list = paid / (1+rate);
17:tax = paid - list;
18:printf(”Прейскурантна ціна = $%8.2f\n”, list);
19:printf(”Заплачений податок = $%8.2f\n”, tax);
20:return 0;
21:}
Значення типу float можуть мати шість або сім значущих цифр, значення типу double - 15 або 16, а long double - 19.Про це свідчить фрагмент файлу FLOAT.Н:
#define DBL_DIG |
15 |
|
#define |
FLT_DIG |
6 |
#define |
LDBL_DIG |
18 |
1.9. Розміри змінних.
Компілятори Cі відрізняються один від одного способом зберігання змінних різних типів. Тому, щоб уникнути непорозумінь, для визначення розміру змінної потрібно використовувати функцію sizeof():

Приклад1.8:
1: #include <stdio.h>
2:
3:main()
4:{
5:char c;
6:short s;
7:int i;
8:long l;
9:float f;
10:double d;
11:long double ld;
13: |
printf(”Size of char …………...... |
= %2d byte(s)\n”, sizeof(с)); |
14: |
printf(”Size of short…………..... |
= %2d byte(s)\n”, sizeof(s)); |
15: |
printf(”Size of int …………........ |
= %2d byte(s)\n”, sizeof(i)); |
16: |
printf(”Size of long.…………...... |
= %2d byte(s)\n”, sizeof(l)); |
|
|
11 |
17: |
printf(”Size of float…………...... |
= %2d byte(s)\n”, sizeof(f)); |
18: |
printf(”Size of double.………..... |
= %2d byte(s)\n”, sizeof(d)); |
19: |
printf(”Size of long double…...... |
= %2d byte(s)\n”, sizeof(ld)); |
20:return 0;
21:}

Примітка!
Коли дозволена видача повідомлень, то при компіляції цього прикладу, буде видано багато попереджень про те, що змінні в програмі описані, але не використовуються.
Особливо корисна функція sizeof(), коли ви будете працювати з агрегатними типами: наприклад, змінними типу структур.
1.10. Символічні (іменовані) константи.
Символічна (іменована) константа є ідентифікатором, який замінює собою константу якого-небудь типу (рядкову, символьну, цілу або дійсну).
Визначення іменованої константи виконується за такою загальною формою:
#define Ім’я_константи Значення_константи
Наприклад, ідентифікатор MAX_PRIZ може позначати максимальну суму призу. Такий ідентифікатор можна оголосити в заголовному файлі (з розширенням .h) або на початку програми:
#define MAX_PRIZ 10000 /* Максимальний приз */
Після цього запису не повинно стояти ніяких знаків обмеження, наприклад, "}" чи ";". Приклади інших визначень символічних констант:
#define NAME ”VASYA PETROV” #define FALSE 0
#define TRUE 1
Символічні константи - це не оголошення змінних. Вони створюють тимчасові символи NAME, FALSE, та TRUE, які позначають текст, який слідує за ними, в тому числі і лапки в першому рядку. Ви можете використовувати символічні константи в будь-якому місці, за виключенням рядкових констант і змінних.
Під час компіляції символічні константи транслюються за допомогою попереднього процесора, який замінює символічну константу на текст, що стоїть справа від неї в директиві #define. Попередній процесор також замінює директиву #include відповідним текстом заголовного або .с файлу (в Borland C++ попередній процесор емулюється).
1.10.1.Попередньо визначені символічні константи.
Вфайлі заголовному MATH.H є визначення символічних констант, наприклад:
#define M_E 2.71828182845904523536
#define M_LN10 |
2.30258509299404568402 |
|
#define |
M_PI |
3.14159265358979323846 |
#define |
M_PI_2 |
1.57079632679489661923 |
Якщо на початку програми вставити рядок <#include math.h>, то вашій програмі стануть доступні ці та інші математичні символічні константи. Якщо вам потрібне значення π у виразі ви повинні написати:
result = M_PI * value;
1.11. Перерахування.
Припустимо, ви хочете представити кольори райдуги. Їх можна було б визначити у вигляді символічних констант:
#define RED |
0 |
|
#define ORANGE |
1 |
|
#define |
YELLOW |
2 |
#define |
GREEN |
3 |
12
#define BLUE |
4 |
|
#define |
INDIGO |
5 |
#define |
VIOLET |
6 |
Після цього можна оголосити змінну цілого типу таким чином: int color;
а потім присвоїти їй будь-яке значення із символів "райдуги": color = YELLOW;
В Cі не потрібен такий довгий шлях. Тут є так званий перераховуючий тип. Використовуючи слово enum, попередню операцію можна виконати так:
enum Colors {RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET};
Загальна форма оголошення перераховуючого типу така:
enum ім’я_перерахування {список_іменованих_констант};
Кожній іменованій константі із списку у фігурних дужках ставиться у відповідність ціле значення починаючи з якогось початкового значення. По замовчанню воно дорівнює нулю. Тобто RED = 0 і т.д. Якщо ви хочете щоб підрахунок значень починався не з нуля, а з якогось іншого значення, то це значення потрібно вказати явним чином:
enum color {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};
При необхідності можна кожній іменованій константі поставити у відповідність значення, які змінюються довільно. Наприклад, у заголовному файлі graphics.h Borland C++ 3.1, який використовується для зв’язку з графічними функціями є визначення перерахування
для роботи з відеоадаптером EGA: |
|
|
|
enum EGA_COLORS { |
= |
0, |
/* темні кольори */ |
EGA_BLACK |
|||
EGA_BLUE |
= |
1, |
|
EGA_GREEN |
= |
2, |
|
EGA_CYAN |
= |
3, |
|
EGA_RED |
= |
4, |
|
EGA_MAGENTA |
= |
5, |
|
EGA_BROWN |
= |
20, |
|
EGA_LIGHTGRAY |
= |
7, |
/* Світлі кольори */ |
EGA_DARKGRAY |
= |
56, |
|
EGA_LIGHTBLUE |
= |
57, |
|
EGA_LIGHTGREEN |
= |
58, |
|
EGA_LIGHTCYAN |
= |
59, |
|
EGA_LIGHTRED |
= |
60, |
|
EGA_LIGHTMAGENTA |
= |
61, |
|
EGA_YELLOW |
= |
62, |
|
EGA_WHITE |
= |
63 |
|
}; |
|
|
|
Оголошення змінної перераховуючого типу виконується за наступною схемою: enum ім’я_перерахування {список_іменованих_констант};
...
enum ім’я_перерахування ім’я_змінної_1[, ім’я_змінної_2...];
Наприклад, змінні перераховуючого типу Colors можна оголосити (чи визначити) так: enum Colors color_1, color_2 = INDIGO;
Якщо включити у свою програму graphics.h, то можна оголошувати змінні перераховуючого типу EGA_COLORS:
enum EGA_COLORS color_3, color_4; color_3 = EGA_LIGHTGREEN;
color_4 = 59;
Перераховуючі типи мають внутрішнє представлення з мінімально можливим об`ємом пам`яті - в знакових або беззнакових типах int чи char.
13
За допомогою ключового слова typedef можна створити новий тип даних для
перераховуючих символічних констант: typedef enum
{
RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET }Colors;
Після цього слово Colors стало ніби оператором опису типу (як, наприклад int, float і т.д.).
Після цього можна оголосити нову змінну та ініціювати її:
Colors One_Color;
One_Color = GREEN ;
Ви можете присвоїти їм також цілі значення: one_Color = 5 ;

Увага!
Не дивлячись на те, що змінним перераховуючого типу відповідають цілі (int чи char) ви не можете присвоїти змінній перераховуючого типу будь-яке ціле значення (із тих, які дозволяють типи int чи char). Змінній перераховуючого типу можна присвоїти тільки ті значення, які присутні в списку_іменованих_констант.
1.12.Використання змінних різних типів в одному виразі.
1.12.1. Перетворення типів.
Не можна забувати, що змінні зберігаються у фіксованій кількості байтів. Змішувати змінні різних типів потрібно обережно. Наприклад, розглянемо такі оголошення:
long get_a_long = 12345678; int int_by_int;
Що станеться, якщо виконати таке присвоєння: int_by_int = get_a_long;
Не дивлячись на те, що змінна int_by_int коротша, ніж get_a_long, компілятор пропустить таку "помилку" і присвоїть їй значення 24910. Чому саме це значення? Тому, що це число є залишком від ділення 12345678 на 65636, яке є найбільшим беззнаковим, що може зберігатися в двох байтах. Тобто значення long, яке зберігається в змінній get_a_long, обрізається, щоб розташуватись в меншій області пам`яті, відведеній для змінної int_by_int типу int. Зворотне присвоєння не викликає ніяких проблем: в цьому випадку змінна типу int розширюється до чотирибайтового значення. Розширення зустрічаються також у виразах, які вміщують значення з плаваючою точкою та цілого типу.
Наприклад:
float float_value; double double_value;
Присвоєння
float_value = double_value;
може викликати проблеми, оскільки змінна типу float не може вмістити значення типу double. Присвоєння значень з плаваючою точкою змінній цілого типу проходить без проблем - тільки губиться дробова частина. Змішування цілих і значень з плаваючою точкою викликає перетворення типів, але результати не завжди передбачувані. Наприклад, розглянемо оголошення:
int i = 4; float f = 2.8;
Апотім такий оператор:
i= f * i;
Чому буде дорівнювати і? Спочатку компілятор розширить і до типу float, помножить це значення на f (4 * 2.8 = 11.2), а потім звузить результат до типу int, тобто і буде дорівнювати 11.
14
Взагалі при обчисленні виразу, в якому присутні змінні та константи різних типів, всі вони спочатку будуть приведені до типу з найвищим пріоритетом, яким володіє хоча б одна із констант або змінних виразу (дивіться таблицю 1.2).
1.12.2. Приведення типів.
Ми можемо примусити компілятор спочатку виконати приведення змінної f із попереднього прикладу до типу int і тільки потім виконати множення (в результаті ми одержимо 8, а не 11). Для цього потрібно використати операцію приведення типів:
i = (int)f *i;
Аналогічно ми можемо зробити для інших сумісних типів (більш детально дивіться [1, 3]).
1.12.3. Змішування знакових і беззнакових змінних.
Змішувати у виразах знакові і беззнакові змінні потрібно обережно, оскільки це дає не завжди очікувані результати. Наприклад:
unsigned u = 0xFFFF; int i = u;
Значення u відповідає десятковому беззнаковому 65535, але змінній і буде присвоєно десяткове знакове -1, яке в шістнадцятковій системі записується як 0xFFFF.
Оскільки значення типу char можуть бути знаковими і беззнаковими цілими, то такий фрагмент програми не дасть однакового результату в різних компіляторах:
char c = '\xf0'; int i = c; printf("i = %d",i);
Символьній змінній с присвоюється значення ASCII '\0xf0', яке еквівалентне знаковому числу 16, а беззнакове значення дорівнює 240. Тому, щоб одержати те, що вам потрібно, використайте оголошення:
unsigned char c;
Або можна скористатись оголошенням символьної змінної, як цілої: int c = 'A';
1.13. Логічна організація простої програми.
Структура простої програми на Сі приведена на рис. 1.2. Директиви #include призначені для того, щоб включити в вашу програму заголовні файли з розширенням “.h” (дивіться розділ 1.5). Блок опису глобальних змінних не є обов’язковим. Глобальні змінні використовуються для організації обміну даними між підпрограмами (дивіться розділ 6.4.2).Структура кожної функції співпадає з структурою головної функції main().
Функція main() в програмі може бути тільки одна, а підпрограм-функцій може стільки, скільки потрібно. Функції можуть мати в складі операторів інші функції, а ті, в свою чергу, викликати інші функції. Більш докладну інформацію про функції дивіться розділ .[6].
1.14. Директиви include.
Поява директив
#include <ім`я_файлу_1>
...
#include <ім`я_файлу_N>
приводить до того, що попередній процесор (або компілятор в режимі емуляції попередній процесора) підставляє на місце цих директив тексти файлів ім`я_файлу_1, …, ім`я_файлу_N.
15
/*Заголовки та коментарії, які описують програму */
/*Директиви include*/
#include ім`я_файлу_1
…
#include ім`я_файлу_N
/* Макроси */
#define макро_1 значення_1
…
#define макро_M значення_M
/*Описи глобальних змінних */
тип_даних глобальна змінна_1;
…
тип_даних глобальна змінна_K;
main ()
{
/*Описи extern, яке забезпечує посилання вперед на функції, які використовуються в тілі функції main ()*/
*Описи локальних змінних */
тип_даних локальна_змінна_1;
…
тип_даних локальна_змінна_L;
/*Тіло функції main ()*/
Оператор_1
…
Оператор_J
}
/*Функції, які використовуються в функції main ()*/
Функція_1
/*Заголовок_функції_1*/
тип_даних ім`я_функції_1(тип_даних ім`я_параметру_1, …, тип_даних ім`я_параметру_G,)
{
1
Рис. 1.2 Логічна структура простої програми на Сі
16
1
/* Опис extern, яке забезпечує посилання вперед на функції, які використовуються в тілі даної функції */
*Описування локальних змінних */
тип_даних локальна_змінна_1;
…
тип_даних локальна_змінна_U;
/*Тіло функції_1*/
Оператор_1
…
Оператор_R
}
Продовження рис. 1.2
Якщо ім`я файлу взяте в кутові дужки, то пошук файлу виконується в спеціальному розділі підстановочних файлів. Звичайно в цьому розділі розміщуються файли з розширенням .h. Наприклад в Borland C++ - це цілий каталог з іменем Include, який вміщує сім підкаталогів і деяких із них також є підкаталоги. Якщо в розділі відсутній такий файл, то попередній процесор видає повідомлення про помилку і процес обробки переривається.
Якщо ім`я файлу взяте в лапки "ім`я_файлу_k", то пошук файлу спочатку почнеться з поточного розділу. Якщо його там нема, система переходить до пошуку файлу в розділі підстановок. Якщо його там не знайдено, то процес переривається.

Примітка.
Подивіться уважно! Після директиви #include крапка з комою не ставиться
1.15. Макроси.
За допомогою директиви #define, слідом за якою записується ім`я та значення макроса, можна вказати попередньому процесору (або компілятору), щоб він при появі в первинному файлі цього імені замінював це ім`я на відповідне значення макроса.
Макроси можуть мати параметри. Наприклад, макрос:
#define square(x) ( (x) * (x) )
задає заміну запису square(аргумент) на значення (аргумент)* (аргумент). Часто макроси використовуються для ув`язування ідентифікатора і значення:
#define pi 3.1415926
(тобто константі 3.1415926 присвоюється символічне ім`я рі).

Попередження! 

Після значення макроса не потрібно ставити крапку з комою.
1.16.Робоче завдання.
1.Знайдіть та виправте помилки в приведеній нижче програмі:
1:include stdio.h
2:
3:main{}
4:(
17
5:int c
6:short s[25];
7:char bovin = 'ox';
8:c := 56:
9:s = "Привіт";
10:printf (s)
11:printf("%c", bovin);
12:printf(%d, c);
13:)
2.Вказати тип та довжину змiнних, якi задано в приведених операторах опису: a) float Real_a;
b) double Double_Precision; c) char Character;
d) unsigned char Unsigned_Char; e) unsigned Unsigned;
3.Напишіть, якими типами ви будете користуватись при обробці наступних даних: a) Кількість жителів міста Києва;
b) Вагу вантажного автомобіля "Татра";
c)Букву, яка найбільш часто зустрічається в цьому тексті;
d)Число π з найбільш можливою точністю;
e)Ваш рік народження.
4.Скласти оператори опису змiнних, якi входять в вираз:
Y=-4.3*S-X*Х/(S-1)+Quin(S);
якщо S - вiдповiдно змiнна дiйсного типу, значення яких займають чотири байти пам'ятi; X - змiнна цiлого типу, яка займає два байти пам'ятi; Y - змiнна дiйсного типу подвійної точності.
5. Скласти оператори явного опису для змiнних, якi входять в вираз:
Y=1.+(0.7E-2*F+D)*C+C1+EXP(X)*(A_1 + A_2)/(K)
якщо F, C, C1 - змiннi дiйсного типу ,значення яких займають вiсiм байт пам'ятi; D - змiнна цiлого типу, яка займає чотири байти пам'ятi без знаку; X, Y - змiннi дiйсного типу, якi мають довжину в чотири байти; A_1 та А_2 −змінні, значеннями яких є вiдповiдно числа: 16,27; 10,0*103, K - дійсне число подвійної точності.
6.Визначити символічні константи: a) Значення елементарного заряду; b) Питомий заряд електрона;
c) Постійну Больцмана; d) Постійну Планка.
7.Визначити нові типи змінних і описати по дві змінних кожного із типів: a) Тип, який би визначав день тижня;
b) Тип, який би визначав вид фруктів, наприклад, яблука, апельсини і тому подібне.
8.Навести приклади:
a)Оголошення змінних;
b)ініціалізації змінних;
c)Визначення змінних.
1.17.Контрольнi запитання.
1.Назвіть базові типи змінних в Сі.
2.Як можна задати тип змiнних?
3.Що таке опис, ініціалізація та визначення змінних?
4.Скількисимволівможутьвключатиідентифікаториіякісимволивониможутьвключати?
5.Які слова входять до переліку зарезервованих слів Сі і що це значить?
6.Назвiть способи, якими можна задати початковi значення змiнним. Наведiть приклади.
7.Наведіть перелік управляючих символів Сі та їх призначення.
8.Що таке ліводопустимі та праводопустимі вирази? Наведіть приклади.
9.Назвіть допустимі операції над цілими та знаки якими вони позначаються в програмах?
10.Для чого потрібні #include - директиви? Наведіть приклади.
11.Для чого потрібні #define - директиви? Наведіть приклади.
12.Як можна створити новий тип даних в Сі? Наведіть приклади.
13.Наведіть структуру простої програми на Сі. Коротко поясність призначення кожного блоку.
18
