
- •1.1 Перші кроки
- •1.2 Змінні й арифметичні вирази
- •1.3 Твердження for
- •1.4 Символічні константи
- •1.5 Ввід і вивід знаків
- •1.5.1 Копіювання файла
- •1.5.2 Відлік символів
- •1.5.3 Відлік рядків
- •1.6 Масиви
- •1.7 Функції
- •1.8 Аргументи - виклик за значенням
- •1.9 Символьні масиви
- •1.10 Зовнішні змінні й область дії
- •2.1 Назви змінних
- •2.2 Типи даних і розміри
- •2.3 Константи
- •2.4 Оголошення
- •2.5 Арифметичні операції
- •2.6 Реляційні та логічні оператори
- •2.7 Перетворення типів
- •2.8 Оператори приросту та спаду
- •2.9 Розрядні оператори
- •2.10 Оператори та вирази присвоєння
- •2.11 Вирази умов
- •2.12 Пріоритет і послідовність обчислення
- •3.1 Вирази та блоки
- •3.3 Else if
- •3.4 Switch
- •3.5 Цикли while та for
- •3.6 Цикли do-while
- •3.7 Break і continue
- •3.8 Goto та мітки
- •4.1 Основні знання про функції
- •4.2 Функції, які не повертають цілих
- •4.3 Зовнішні змінні
- •4.4 Правила області дії
- •4.5 Файли заголовка
- •4.6 Статичні змінні
- •4.7 Регістрові змінні
- •4.8 Структура блоків
- •4.10 Рекурсія
- •4.11 Препроцесор c
- •4.11.1 Включення файлів
- •4.11.2 Заміна макросів
- •4.11.3 Обумовлене включення файлів
- •5.1 Покажчики й адреси
- •5.2 Покажчики й аргументи функцій
- •5.3 Покажчики та масиви
- •5.4 Арифметика адрес
- •5.5 Покажчики на символи та функції
- •5.6 Масив покажчиків; покажчики на покажчики
- •5.7 Багатовимірні масиви
- •5.8 Ініціалізація масиву покажчиків
- •5.9 Покажчики в порівнянні з багатовимірними масивами
- •5.10 Аргументи командного рядка
- •5.11 Покажчики на функції
- •5.12 Складні оголошення
- •6.1 Основні поняття про структури
- •6.2 Структури та функції
- •6.3 Масиви структур
- •6.4 Покажчики на структури
- •6.5 Структури зі зворотнім звертанням
- •6.6 Пошук по таблиці
- •6.7 Typedef
- •6.8 Сполуки
- •6.9 Розрядні поля
- •7.1 Стандартний ввід і вивід
- •7.2 Форматований вивід - printf
- •7.3 Списки аргументів довільної довжини
- •7.4 Форматований ввід - scanf
- •7.5 Доступ до файлів
- •7.6 Обробка помилок - stderr і exit
- •7.7 Ввід і вивід рядків
- •7.8 Додаткові функції
- •7.8.1 Операції з ланцюжками
- •7.8.2 Перевірка і перетворення класів символів
- •7.8.3 Ungetc
- •7.8.4 Виконання команд
- •7.8.5 Керування пам'яттю
- •7.8.6 Математичні функції
- •7.8.7 Генератор випадкових чисел
- •8.1 Дескриптори файлів
- •8.2 Низькорівневий ввід/вивід - read і write
- •8.3 Open, creat, close, unlink
- •8.4 Довільний доступ - lseek
- •8.5 Приклад: втілення fopen і getc
- •8.6 Приклад - перелік вмісту каталогів
- •8.7 Приклад - розподільник пам'яті
4.8 Структура блоків
C не являється блок-структурованою мовою на зразок Pascal чи інших мов, оскільки функцію не можна означити всередині іншої функції. З іншого боку, змінні можуть бути описані у блок-структурованому вигляді всередині функції. Оголошення змінних (включаючи ініціалізацію) може слідувати за лівою фігурною дужкою, яка започатковує будь-яке складене твердження, а не тільки починає функцію. Змінні, оголошені таким чином, приховано від однаково названих змінних у зовнішніх блоках і залишаються існувати до відповідної правої фігурної дужки. Наприклад, у
if (n > 0) {
int i; /* оголошення нової i */
for (i = 0; i < n; i++)
...
}
зоною дії змінної i є «істинне» відгалуження if; це не матиме жодного стосунку до жодного i поза межами цього блока. Автоматичну змінну, оголошену та ініційовану у блоці, ініційовано кожний раз при входженні у цей блок.
Автоматичні змінні, включаючи формальні параметри функцій, також приховані від зовнішніх змінних і функцій з тією самою назвою. Маючи оголошення
int x;
int y;
f(double x)
{
double y;
}
змінна x, як параметр функції f типу double, немає нічого спільного з зовнішньою x типу int. Те саме стосується змінної y. Але, загалом, краще уникати назв змінних, що співпадають з назвами з інших зон дії, занадто велика ймовірність плутанини і помилок.
4.9 Ініціалізація
Про ініціалізацію мимоходом вже згадувалося багато разів, але зважди периферійно, як частина іншої теми. Цей розділ підводить підсумок декяких правил, після того як ми оговорили різноманітні типи зберігання. У випадку відсутності явної ініціалізації, зовнішні і статичні змінні буде гарантовано надано значення нуль. Автоматичні і регістрові змінні матимуть невизначене початкове значення (тобто непотріб).
Скалярні змінні можуть бути ініційованими під час їхнього визначення шляхом додачі до їхньої назви знака рівності і виразу:
int x = 1;
char squota = '/'';
long day = 1000L * 60L * 60L * 24L; /* мілісекунд у день */
Для зовнішніх і статичних змінних, ініціалізатор повинен бути сталим виразом; ініціалізація бідбувається один раз, концептуально до того як програма починає виконуватись. Для автоматичних і регістрових змінних, ініціалізатор не обов'язково повинен бути константою: це може бути будь-який вираз, включаючи попередьно-визначенні значення, навіть виклики функцій. Так, наприклад, ініціалізацію в програмі бінарного пошуку з Розділу 3.3 може бути написано як
int binsearch(int x, int v[], int n)
{
int low = 0;
int high = n - 1;
int mid;
...
}
замість
int low, high, mid;
low = 0;
high = n - 1;
Ефективно, ініціалізація автоматичних знінних, це просто скорочення для виразів присвоєння значення. Якій формі надавати перевагу, це значною мірою є питанням змаку. Ми загалом використовували явні присвоєння, оскільки ініціалізатори у оголошеннях важче побачити і знаходяться далі від місця використання.
Масив може бути ініційовано через додання до оголошення списку ініціалізаторів, включених у фігурні дужки і розділених комою. Як приклад — ініціалізація масиву days з кількістю днів кожного місяця:
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Коли розмір масиву не вказано, компілятор обчислить його, перелічивши ініціалізатори, 12 у цьому випадку.
Якщо надано менше ініціалізаторів, ніж вказаний розмір масиву, решті буде присвоєне значення нуль у випадку зовнішніх, статичних і автоматичних змінних. Помилка виникне у випадку зайвих ініціалізаторів. Не існує способу вказати повторні ініціалізатори, так само як елемент посередині масиву, без вказівки попередніх значень також.
Символьні масиви — це спеціальний випадок ініціалізаторів: можна використати ланцюжок замість нотації з фігурних дужок і ком:
char pattern[] = "ould";
що є скороченням для довшого, але рівнозначного
char pattern[] = { 'o', 'u', 'l', 'd', '\0' };
У обох випадках, масив складатиметься з п'яти елементів: чотири літери і кінцевий '\0'.