Теоретичні відомості#
Типи даних у мові С#
Типи даних служать для опису змінних. Імені змінної відповідає адреса ділянки пам’яті, виділеної для зберігання значення змінної, а довжина цієї ділянки залежить від типу вибраних даних. Тип змінної, крім цього, визначає множину допустимих значень, які може зберігати змінна, а також набір операцій, для яких змінна може служити операндом. Множина допустимих значень зазвичай збігається з множиною допустимих констант того ж типу. Існують символьні, цілочисельні й дійсні змінні. При цьому символьні змінні в мові С можна розглядати як цілочисельні.
Змінні типізують на основі визначень та описів. Визначення, на відміну від опису, не тільки уводить програмний об’єкт, але й дає вказівку компілятору виділити ділянку пам’яті для його розміщення в пам’яті ЕОМ. Для визначень та описів змінних використовують такі ключові слова: char
, short
, int
, long
, float
, double
. Крім цього, як окремо, так і з іншими ключовими словами можна використовувати слова signed
і unsigned
. Вони позначають знаковий або беззнаковий вид зберігання цілого числа, відповідно.
Прості типи даних мови С коротко представлено в таблиці 1.1.
Таблиця 1.1 – Базові типи даних мови С
Тип |
Мінімальний розмір, біт |
Діапазон значень |
---|---|---|
|
8 |
-128…127 |
|
8 |
0…255 |
|
16 |
-32768…32767 |
|
16 |
-32768…32767 |
|
16 |
0…65535 |
|
16 |
-32768…32767 |
|
16 |
0…65535 |
|
32 |
-2147483648…2147483647 |
|
32 |
0…4294967295 |
|
64 |
-9223372036854775808…9223372036854775807 |
|
64 |
0…18446774073709551615 |
|
32 |
3,4e-38…3,4e+38 |
|
64 |
1,7е-308…1,7е+308 |
|
80 |
3,4е-4932…1,1е+4932 |
Особливістю типу int
є те, що його довжина в байтах відповідає ширині шини даних комп’ютера, для якого розроблено використовуваний компілятор. Типи даних float
, double
і long double
уважають невпорядкованими.
Для опису типу значення, яке повертає функція, можна використовувати ключове слово void
, що означає відсутність результату. У цьому випадку функція нічого не повертає.
Константи в мові С#
Константа являє собою мовну конструкцію, що позначає зображення фіксованого числового, рядкового або символьного значення. Їх розділяють на п’ять груп: цілі, дійсні, перелічувані, символьні, рядкові. Перелічувані константи зазвичай відносять до цілочисельного типу даних.
Ціла константа може бути десятковою, вісімковою або шістнадцятковою. Десяткова константа являє собою набір десяткових цифр, що починається з цифри, відмінної від нуля, якщо це не нуль. Від’ємні константи являють собою константи без знаку, до яких застосовано операцію зміни знаку. Вісімкові константи завжди починаються з нуля. У їх запису неприпустиме використання цифр 8 і 9. Шістнадцяткова константа починається з символів 0х
. До її складу можуть входити цифри від 0 до 9 і літери латинського алфавіту від A до F (позначають числа від 10 до 15, відповідно).
За замовчуванням, цілочисельні константи належать до типу int
. Можна явно вплинути на вибір типу даних для константи. Для цього служать суфікси l
, u
та ul
. Суфікс l
відповідає типу long
, u
— типу unsigned int
, ul
визначає тип unsigned long
.
Дійсна константа має іншу форму подання, яка використовує арифметику з плаваючою крапкою. Константа з плаваючою крапкою може мати сім частин: знак, ціла частина, десяткова крапка, дробова частина, ознака експоненти е
або Е
, показник десяткового ступеня, суфікс l
або f
. У випадку відсутності суфіксів дійсна константа належить до типу double
. Суфікс f
відносить константу до типу float
, а суфікс l
— до типу long double
.
Перелічувані константи уводять за допомогою службового слова enum
. По суті, це — звичайні цілочисельні константи, яким приписано унікальні ідентифікатори, що не збігаються з іншими програмними об’єктами та службовими словами. Кожній такій константі присвоюється цілочисельне значення. Першому ідентифікатору в переліку присвоюється значення нуля, а значення кожного наступного збільшується на одиницю.
Символьні константи являють собою один або два символи, укладені в апострофи. Односимвольні константи належать до стандартного типу char
. Запис кодів і символів '
, \
, ?
, "
повинен починатися з символу '\'
(зворотний слеш). Послідовності, що починаються з символу '\'
, називають esc-послідовностями (від англійського слова escape).
Рядок являє собою послідовність символів, оточену лапками. Розміщуючи рядок в пам’яті, компілятор автоматично додає в його кінець нульовий символ ('\0'
).
Деякі функції стандартного уведення-виведення#
Функція printf()
дає можливість виводити інформацію на екран за програмування в консольному режимі. Дану функцію визначено в бібліотеці stdio.h
. Вона має такий синтаксис:
int printf(const char* format[,argument]…);
де *format
визначає рядок, який виводиться на екран і може містити спеціальні керуючі символи для виведення змінних;
далі слідує список необов’язкових аргументів, які пояснюються нижче.
Функція printf()
повертає або число відображених символів, або від’ємне число (у випадку некоректної роботи).
За допомогою функції printf()
можна виводити змінні різного типу, починаючи з числових і закінчуючи рядковими. Для цього використовують спеціальні керуючі символи, які називають специфікаторами і які починаються з символу %
. Наступний приклад демонструє виведення цілочисельної змінної num на екран за допомогою функції printf()
:
int num;
num = 5;
printf("%d", num);
У перших двох рядках фрагменту програми задається змінна з іменем num
типу int
. У третьому рядку виконується виведення змінної на екран.
Робота функції printf()
виглядає так. Спочатку функція аналізує рядок, який потрібно вивести на екран. У даному випадку це — "%d"
. Якщо в цьому рядку зустрічається специфікатор, то на його місце записується значення змінної, яка є другим аргументом функції printf()
. У результаті замість початкового рядка "%d"
на екрані з’явиться рядок "5"
, тобто буде виведено число 5.
Специфікатор "%d"
виводить тільки цілочисельні типи змінних, наприклад int
. Для виведення інших типів потрібно використовувати інші специфікатори. Нижче перераховано основні специфікатори:
%с
— одинарний символ;%d
— десяткове ціле число зі знаком;%f
— число з плаваючою крапкою (десяткове подання);%s
— рядок символів (для рядкових змінних);%u
— десяткове ціле число без знаку;%%
— друк знаку відсотка.
За допомогою функції printf()
можна виводити декілька змінних одночасно.
Крім специфікаторів, у функції printf()
використовують керуючі символи, такі як переведення рядка \n
, табуляції \t
та ін.
Для уведення інформації з клавіатури зручно використовувати функцію scanf()
із бібліотеки stdio.h
, яка має такий синтаксис:
int scanf(const char* format[,argument]…);
де *format
визначає форматний рядок для визначення типу даних, які уводять, і може містити специфікатор, аналогічний функції printf()
;
інші параметри — список адрес змінних, у які уводять дані. У цьому списку перед іменами всіх змінних, крім тих, які уводять за специфікацією типу %s
, повинен стояти символ &
.
Варто відмітити істотну різницю між функціями scanf()
і printf()
. У функції printf()
після рядка йде перелік імен змінних, а не їхніх адрес, тоді як параметри функції scanf()
визначають адреси змінних, які уводять, тобто яким змінним буде присвоєно уведені значення. Для позначення адреси змінної мовою С перед її іменем ставлять амперсанд &
.
Функція putchar()
слугує для виведення одного символу на екран. Вона має такий синтаксис:
int putchar(int ch);
де ch
— код символу, який виводять.
У випадку успішного виконання функція повертає цей же код, неуспішного — константу EOF
.
Функція getchar()
слугує для уведення одного символу з клавіатури. Вона має такий синтаксис:
int getchar(void);
Функція повертає код уведеного символу.
Функція puts()
слугує для виведення рядка символів на екран. Вона має такий синтаксис:
int puts(char* string);
де *string
— указівник на початок того рядка, із якого виводять дані.
Функція повертає кількість виведених символів.
Функція gets()
слугує для уведення рядка символів із клавіатури. Вона має такий синтаксис:
char* gets(char* string);
де *string
— указівник на початок того рядка, у який уводять дані.
Функція повертає той самий указівник.
Бітові операції та операції зсуву#
Як відомо будь-які дані, записані в пам’ять комп’ютера, є послідовністю бітів, тобто послідовністю нулів та одиниць. Наприклад, будь-яке число типу int
займатиме в пам’яті 4 байти, тобто 32 біти. Його можна розглядати або як ціле число (що й роблять під час виконання операцій *
, /
, +
, -
, %
), або як послідовність бітів, що можливо під час використання бітових операцій.
Бітові операції дають змогу виконувати перевірку та зміну окремих бітів у даних цілого та символьного типів. Їх не можна використовувати для дійсних чисел. Дія бітових операцій ідентична дії логічних операцій, але перші виконують над кожним бітом даних.
Кожна з бітових операцій служить певним цілям. Наприклад, операція &
(and) корисна для перевірки одиничних значень окремих бітів числа, а також для установки певних бітів у 0. Операція |
(or) корисна для установки бітів в 1. Операцію ^
(xor) використовують для перевірки неоднаковості бітів.
Варто зазначити, що результатом бітової операції, на відміну від логічних, буде число символьного або цілочисельного типу, а не логічні 0 або 1. Бітові операції виконують незалежно над кожним бітом даних. Якщо операція двомісна, то її виконують над відповідними бітами операндів. У мові С наявні такі бітові операції:
~
— бітове заперечення (одномісна);&
— побітове І (двомісна);^
— побітове АБО (двомісна);|
— побітове ЧИ (двомісна).
Розгляньмо декілька прикладів.
Перший приклад показує, як за допомогою операції |
встановити в 1 вибрані біти операнда:
char a, b;
a = 9; /* а = 00001001 = 9*/
b = a | 26; /* b = 00011011 = 27*/
Наступний приклад показує, як за допомогою операції &
занулити старшу частину байта:
char a, b;
a = 45; /*а = 00101101 = 45*/
b = a & 0x0F; /*b = 00001101 = 13*/
До бітових операцій належать операції зсуву <<
і >>
, які дають змогу зсунути всі біти числа вліво і вправо на задану кількість розрядів, відповідно:
a << b
— зсув бітів змінноїa
вліво наb
позицій;a >> b
— зсув бітів змінноїa
вправо наb
позицій.
Відсутні значення бітів доповнюють нулями, інформація в зникаючих бітах втрачається.
Наприклад:
char a, b;
a = 26; /*a = 00011010 = 26*/
b = a << 2; /*b = 01101000 = 104*/
Зсув уліво рівносильний множенню на 2 у відповідному ступені, управо — діленню на 2 у відповідному ступені. Усі бітові операції виконують зліва направо. У наступному рядку наведено бітові операції в порядку зменшення їхнього пріоритету:
~, <<, >>, &, ^, |
Для двомісних бітових операцій визначено операції присвоювання:
a <<= b
еквівалентноa = a << b
,a >>= b
еквівалентноa = a >> b
,a &= b
еквівалентноa = a & b
,a ^= b
еквівалентноa = a ^ b
,a |= b
еквівалентноa = a | b
.