
- •12. Класи пам'яті даних 100
- •13. Робота з файлами 106
- •14. Посилання 111
- •Склад мови
- •Алфавіт мови
- •Лексеми
- •Ключові слова
- •Ідентифікатори
- •Константи
- •Символьні рядки
- •Знаки операцій, роздільники, коментарі
- •Типи даних
- •Класифікація типів даних
- •Цілочислові типи
- •Дійсні типи
- •Оголошення змінних і констант
- •Переліки
- •Структура програми
- •Функція main
- •Область дії змінної
- •Введення і виведення даних
- •Функції стандартної математичної бібліотеки
- •Вирази і операції
- •Поняття виразу, операнда, операції
- •Порядок виконання операцій
- •Арифметичні операції
- •Порозрядні операції
- •Операції порівняння
- •Логічні операції
- •Операції присвоєння
- •Умовна операція
- •Операція визначення розміру sizeof
- •Узгодження типів у виразах
- •Умовні оператори
- •Оператори
- •Умовний оператор if
- •Оператор вибору switch
- •Оператори циклу
- •Цикл з параметром. Оператор for
- •Цикл з передумовою. Оператор while
- •Цикл з постумовою. Оператор do while
- •Оператори переходу
- •Використання псевдовипадкових чисел
- •Одновимірні масиви
- •Багатовимірні масиви
- •Символьні рядки
- •Вказівники
- •Оголошення вказівника, операції, пов’язані з вказівниками
- •Адресна арифметика
- •Void – вказівники, типізація вказівників
- •Звертання до елементів масивів через вказівники
- •Масиви символьних рядків і масиви вказівників
- •Динамічне виділення пам’яті
- •Структури і об’єднання
- •Оголошення і ініціалізація структур
- •Звертання до елементів структур
- •Перейменування типів
- •Об’єднання
- •Поля бітів
- •Директиви препроцесора
- •Призначення директив препроцесора
- •Директива включення #include
- •Директиви макропідстановок #define I #undef
- •Директиви умовної компіляції
- •Директиви #ifdef, #ifndef
- •Функції
- •Структура функції
- •Виклик функцій. Прототипи функцій
- •Взаємодія фактичних і формальних параметрів функцій
- •Inline – функції
- •Масиви і символьні рядки як параметри функцій
- •Використання кваліфікатора const в оголошеннях параметрів
- •Багатовимірні масиви як параметри функцій
- •Опрацювання структур у функціях
- •Вказівники на функції
- •Рекурсивні функції
- •Класи пам'яті даних
- •Клас пам'яті, час існування і видимість об’єкта
- •Область дії глобальних і локальних змінних
- •Специфікатори класів пам'яті
- •Специфікатори глобальних змінних
- •Багатофайлові програми
- •Робота з файлами
- •Звертання до файлів
- •Послідовний запис до файлу і послідовне читання з файлу
- •Файли з довільним доступом
- •Посилання
- •Призначення посилань
- •Передача аргументів функцій як посилань
Специфікатори глобальних змінних
В оголошеннях глобальних змінних можна використовувати тільки специфікатори static i extern. Ці специфікатори найчастіше застосовують при створенні багато файлових програм.
Кожна глобальна змінна має бути визначена (тобто описана) тільки один раз, в разі багато файлових програм – в одному з файлів. Опис змінної пов’язаний з виділенням для неї оперативної пам'яті, обсяг якої визначається типом цієї змінної. Для глобальної змінної пам’ять виділяється в сегменті даних програми і заповнюється нулями, якщо в описі змінну не ініціалізують іншим значенням.
В описах змінних зовнішнього рівня або взагалі не використовують специфікаторів, або вказують специфікатор static – в цьому випадку це означає, що областю дії даної змінної буде частина програми від опису змінної до кінця файлу. В інших файлах програми ця змінна недоступна, тому усувається загроза випадкової зміни її значення. Крім того, в інших файлах можна використовувати свої глобальні змінні з тим самим іменем, оскільки всі однойменні змінні з специфікатором static незалежні.
Кожен програмний файл багато файлової програми може компілюватись автономно. Тому, щоб забезпечити можливість звертання до глобальних змінних, описаних в інших файлах, треба в даному файлі оголосити потрібні глобальні змінні ще раз з використанням специфікатора extern. Таке оголошення не пов’язане з виділенням пам'яті для змінних, отже змінні з специфікатором extern не можна ініціалізувати – вони є посиланнями на відповідні зовнішні змінні та роблять ці змінні видимими (оголошеними) в межах поточного файлу.
Таким чином, кожен об’єкт програми повинен бути описаний тільки один раз, але може бути оголошений багаторазово. Найчастіше це стосується прототипів функцій і змінних з специфікатором extern. Для більшості змінних програми описи та оголошення збігаються.
Багатофайлові програми
В невеликих за розміром програмах функцію main і всі інші функції доцільно записувати в одному текстовому файлі. Якщо програма велика і складна, то доцільно поділити її на декілька програмних файлів, код кожного з яких можна створювати і компілювати автономно.
У багато файлових програмах питання видимості постають у межах одного файлу та на меж файловому рівні. Встановлено такі правила:
об’єкти, оголошені на зовнішньому рівні (тобто між функціями), є частково глобальними, область їх дії – від точки оголошення до кінця програмного файлу;
щоб звернутись до глобальної змінної, описаної в іншому файлі, необхідно в поточному файлі оголосити цю змінну з специфікатором extern;
функції є глобальними об’єктами, тобто вони описуються тільки один раз, областю їх дії є вся програма;
прототипи функцій є частково видимими, вони діють в межах одного програмного файлу.
Згідно з третім правилом кожна функція повинна бути описана тільки один раз в програмі у якомусь з файлів. Для звертання до функції з інших файлів або перед її описом у тому ж файлі треба попередньо вказати прототип функції. Областю дії прототипу функції є один програмний файл, тому в кожному файлі програми треба окремо оголошувати прототипи всіх необхідних функцій.
Зазвичай створюють заголовний файл, в якому записують декларації шаблонів структурних типів і прототипи функцій і файл з розширенням срр, в якому функції описані повністю. Наприклад:
#include <iostream>
#include "fibonachi.h"
using namespace std;
int main( ) {
cout << fib( 46 );
}
// fibonachi.h
#ifndef FIBONACHI
#define FIBONACHI
long fib( long n );
#endif
// fibonachi.cpp
#include "fibonachi.h"
static long knownf[ 47 ];
void init_fibo( void ) {
knownf[ 0 ]=0;
knownf[ 1 ]=1;
for( int i = 2; i < 47; i++ )
knownf[ i ] = -1;
}
long fib( long n ) {
static int num;
if ( ++num == 1 ) init_fibo( );
if ( knownf[ n ] != -1 )
return knownf[ n ];
else {
knownf[ n ] = fib( n - 1 ) + fib( n - 2 );
return knownf[ n ];
}
}