- •Конспект лекцій
- •Вираз 1; while (вираз 2) { тіло вираз 3;
- •Специфікації при введенні і виведенні інформації.
- •Функція printf().
- •Функція виведення рядків puts().
- •Виведення символів на екран - putchar().
- •Перетворення при обчисленні виразів.
- •Арифметичні операції
- •4. Операції присвоювання.
- •5. Повітові операції
- •Функції введення інформації. Функція scanf().
- •Функція gets().
- •Функція fgets().
- •Функція getchar().
- •If (вираз) оператор
- •If (вираз) оператор 1
- •If (вираз 1)
- •Оголошення масиву
- •Покажчики і масиви.
- •Масивів.
Покажчики і масиви.
В мові Сі існує сильний взаємозв'язок між покажчиками і масивами, настільки сильна, що покажчики і масиви дійсно слід розглядати одночасно. Будь-яку операцію, яку можна виконати за допомогою індексів масиву, можна зробити і за допомогою покажчиків. Варіант з покажчиками звичайно виявляється більш швидким, але і дещо більш важким для безпосереднього розуміння, принаймні для початківця. Опис:
INT А[10];
визначає масив розміру 10, тобто набір з 10 послідовних об'єктів, званих А[0], А[1] А[9]. Запис А[І] відповідає елементу масиву через І позицій від початку. Якщо РА - покажчик цілого, описаний як
INT*PA; то привласнення:
РА = &А[0];
призводить до того, що РА указує на нульовий елемент масиву А; це означає, що РА містить адресу елемента А[0]. Тепер привласнення
X = *РА; копіюватиме вміст А[0] в X.
Якщо РА указує на деякий певний елемент масиву А, то за визначенням РА+1 указує на наступний елемент, і взагалі РА-І указує на елемент, що стоїть на І позицій до елемента, указуваного PA, а РА+І на елемент, що стоїть на І позицій після. Таким чином, якщо РА указує на А[0], то
*(РА+1);
посилається на вміст А[1], РА+І - адреса А[І], а *(РА+І) - одержиме А[І].
Очевидно існує дуже тісна відповідність між індексацією і арифметикою покажчиків. Насправді компілятор перетворить посилання на масив в покажчик на початок масиву. В результаті цього ім'я масиву є вказівним виразом. Звідси витікають декілька вельми корисних слідств. Оскільки ім'я масиву є синонімом місцеположення його нульового елемента, то привласнення РА=&А[0] можна записати як
РА = А;
Ще більш дивним, принаймні на перший погляд, здається той факт, що посилання на А[І] можна записати у вигляді *(А+І). При аналізі виразу А[І] в мові Сі воно негайно перетвориться до вигляду *(А+І); ці дві форми абсолютно еквівалентні. Якщо застосувати операцію & до обох частин такого співвідношення еквівалентності, то ми отримаємо, що &А[І] і А+І теж ідентичні: А+І - адреса 1-го елемента від початку А. З другого боку, якщо РА є
покажчиком, то у виразах його можна використовувати з індексом: РА[І] ідентично *(РА+І). Коротше, будь-який вираз, що включає масиви і індекси, може бути записаний через покажчики і зсуви і навпаки, причому навіть в одному і тому ж твердженні.
Є одна відмінність між ім'ям масиву і покажчиком, яке необхідно мати на увазі. Покажчик є змінною, так що операції РА=А і РА++ мають сенс. Але ім'я масиву є константою, а не змінною: конструкції типу А=РА або А++, або Р=&А будуть незаконними.
Багатовимірні масиви.
В мові Сі передбачені прямокутні багатовимірні масиви, хоча на практиці існує тенденція до їх значно більш рідкісного використання в порівнянні з масивами покажчиків.
Масив масивів або багатовимірний масив визначається шляхом завдання списку константних виразів в квадратних дужках, наступного за декларатором:
<специфікатор типу><декларатор>[<константний вираз>]
[<константний вираз>]...
Кожний константний вираз в квадратних дужках визначає число елементів в даному вимірюванні масиву, так що оголошення двовимірного масиву містить два константні вирази, трьохвимірного- три і т.д. Якщо багатовимірний масив оголошується усередині функції або якщо він ініціалізується, або оголошується як формальний параметр, або оголошується як посилання на масив, явно визначений десь в програмі, то перший константний вираз може бути опущений.
Наприклад:
Float Нор[10][10];
IntA[2][3][3];
Двовимірне уявлення - всього лише зручний спосіб візуалізації масиву, що має два індекси. В пам'яті комп'ютера такий масив зберігається послідовно, починаючи з першого елемента.
Перший індекс багатовимірного масиву також має індекс 0. Взагалі, все розглянуте раніше щодо одновимірних масивів має відношення і до багатовимірних.
Динамічне виділення пам'яті.
Об'єм пам'яті, необхідний для зовнішніх, статичних і зовнішніх статичних класів пам'яті, відомий під час компіляції, і дані, що зберігаються в цій секції, доступні під час виконання програми. Кожна змінна з цих класів виникає при запуску програми і зникає, коли робота програми завершена.
Автоматична змінна створюється, коли програма передає управління блоку коду, що містить визначення змінної, і руйнується, коли блок закінчує виконання. Тому, оскільки функції викликають програми, а потім час роботи функцій закінчується, то об'єм пам'яті, що використовується автоматичними змінними, то збільшується, то зменшується. Ця секція пам'яті звичайно обробляється як стек. Це означає, що нові змінні послідовно додаються в пам'ять в тому порядку, в якому вони були створені, а потім вони видаляються в порядку, протилежному надходженню.
Динамічно розподілена пам'ять з'являється, коли викликається функція malloc() або інша, пов'язана з нею, і вивільняється при зверненні до функції free(). Постійність об'єму пам'яті регулюється програмістом, а не набором жорстких правил, так що блок пам'яті може бути створений в одній функції, а розпоряджатися їм можна з іншій функції. Через це частина пам'яті, що використовується для динамічного розподілу пам'яті, може виявитися фрагментованою, тобто невикористані ділянки пам'яті можуть виявитися серед її активних блоків. Використання динамічної пам'яті відноситься до більш повільних процесів, ніж використовування пам'яті стека.
Символьні рядки. Правила описи й ініціалізації символьних
