
- •13. Особливості роботи з порожніми показниками (типу void).
- •Int main ()
- •20. Варіанти оголошень посилальних параметрів
- •1. Клас пам'яті, час існування та видимість об'єкта
- •Int main ()
- •3. Зовнішні змінні функції
- •5. Простір імен
- •Int main ()
- •6. Вбудовані (inline-) функції.
- •Int main()
- •8. Стек і функції (обробка рекурсивних викликів).
- •7. Поняття рекурсивних функцій.
- •Int main ()
- •9. Математичні функції
- •11. Поняття показника.
13. Особливості роботи з порожніми показниками (типу void).
Покажчики – змінні, які зберігають адреси іншої змінної. Найчастіше ці адреси позначають місцезнаходження в пам'яті інших змінних. Наприклад, якщо змінна x містить адресу змінної y, то про змінну x говорять, що вона "вказує" на y. Змінні-покажчики (або змінні типу покажчика) мають бути відповідно оголошені. Формат оголошення змінної-покажчика є таким:
тип *ім'я_змінної;
У цьому записі елемент тип означає базовий тип покажчика, причому він повинен бути допустимим С++-типом. Елемент ім'я_змінної є іменем змінної-покажчика.
В мові С++ виділяють окремий тип показників, що називають порожніми (void). Вони можуть вказувати на об’єкт будь-якого типу. Для отримання доступу до об’єкта. На який вказує показник void треба його перевезти до того ж типу, що і тип самого об’єкта.
//модифікатор з допомогою непрямої адресації і порожнього показника void
# include<iostream.h>
Int main()
{
Char Let=’T’;
Int nNum =’ф’;
Void *ptr;
Ptr=& Let;
*(char*)ptr=’L’;
Ptr = & nNum;
*(int*) ptr=43;
Cout <<Let<<”\n”;
Cout <<nNum;
Return 0;
}
Домовленість про використання нульових покажчиків
Оголошений, але не ініціалізований покажчик міститиме довільне значення. Під час спроби використати покажчик до присвоєння йому конкретного значення можна зруйнувати не тільки власну програму, але навіть і операційну систему (найгірший, треба сказати, тип помилки!). Оскільки не існує
гарантованого способу уникнути використання неініціалізованого покажчика, то С++-програмісти прийняли процедуру, яка дає змогу уникати таких жахливих помилок. За домовленістю, якщо покажчик містить нульове значення, то вважається, що він ні на що не посилається. Це означає, що у випадку присвоєння нульового значення всім невживаним покажчикам і уникати його використання, то можна уникнути випадкового використання неініціалізованого покажчика. Рекомендуємо і Вам дотримуватися цієї практики програмування.
14. Для показників можуть застосовуватися арифметичні операції. Компілятор знаючи тип показника обчислює розмір змінної цього типу, після цього модифікує адресу, що міститься в показнику у відповідності із заданими арифметичними операціями, але з урахуванням обчисленого для цього типу розміру.
Int main ()
{
Float var;
Float *ptr=&var;
Cout<<ptr<<”\n”;
ptr++;
cout<<ptrl
return 0;
}
Крім того показники можна віднімати один від одного визначаючи тим самим к-сть елементів того ж типу на який вказують показники, що розміщені між ними. Також можливі такі відношення і операції (р1,р2 – показники):
р1==р2
р1!=р2
р1<=р2
р1<р2
р1>=p2
р1>р2
p2-p1
p1+n
p1-n
15.Оператори new і delete використовуються для роботи із динамічною пам`яттю для простих змінних. Оператор new має вигляд:
new тип_об`єкта
Наприклад newunsignedshortint виділяє 2 байта для типу. Крім того повертає адресу виділеної пам`яті і ця адреса повинна присвоюватись показнику. Коли пам`ять, що виділяється під змінну більше не потрібна, то її треба звільнити. Для цього використовують оператор delete. Він має такий вигляд:
delete ім`я_змінної_показникового_типу
Якщо вчасно не звільнити область пам`яті, що виділяється під деякий показник, то може статися "витік пам`яті".
Показник на відмінну від області пам`яті є локальною функцією, тому після виходу із функції в якій показник був обов`язковий, цей показник стане недоступним, однак область пам`яті виділена оператором new залишилася. В результаті пам`ять стає недоступною (це і є витік). До завершення виконання пам`ять буде недоступною. І тому оператори
new і delete використовуються в парі.
Sizeof(показник) - показує у байтах розмір змінної.
16. Поняття витоку пам’яті при роботі з показниками.
Принцип динамічної організації памяті полягає у тому, що для змінних надається пам'ять за необхідністю. Далі ці змінні опрацьовуються і в потрібний момент пам'ять вивільнюють (за вказівкою програміста). Такі змінні називаються динамічними. Для роботи з динамічними змінними використовують вказівники.При виділенні динамічної памяті застосовується команд а new так: <тип вказівника>*<назва> = new <тип змінної>;
Дія команди new .Для відповідного типу змінонної автоматично надається необхідна неперервна ділянка памяті . Команда new повертає обсяг цієї ділянки, а вказує на її початок. Наприклад щоб зарезервувати у пам'яті комп’ютера область для зберігання значення цілого типу, застосовують таку команду: int *ptr = new int;
Надати ділянку памяті й відразу занести у неї значення можна так: int * ptr2 = new float(3.14);
У адресу, на яку показує ptr2 ,буде занесено число 3.14. З динамічною змінною можна виконувати операції , визначені для даних відповідного базового типу. Після опрацювання динамічних змінних пам'ять необхідно вивільнити, а відповідний вказівник занулити. Якщо цього не зробити, то пам'ять може вичерпати, цю проблему називають витоком памяті . Вивільнюють пам'ять за допомогою команди: <назва вказівника>= NULL; Значенням (адресою) такого вказівника буде нульова адреса 0х00000000. Тут не може бути розміщене значення жодного даного. Приклад:
#include <iostream.h>
void main()
{
int *c1 =new int; // Готуємо пам'ять для цілого числа
*c1 = 5; //Змінна *c1 набуває значення 5
int *c2 =new int(7); //Виділяється пам'ять для c2 і *c2 набуває значення 7
cout<< *c1<<”\t” << “c2”<<”\n”; //Виводимо 5 та 7
//Переадресація – с1вказуватимо на ту саму
c1=c2; // ділянку памяті, що і с2
cout<<*c1<<”\t”<<*c2<<”\n”; // Виводимо 7 та 7
delete(c2); //Пам'ять надану для с2,вивільнюємо
cout<<*c1<<”n\”; //Виводимо 7
}
18.Показники на функції. Ім`я функції само по собі є константним показником, тобто містить адресу входу до неї. Однак можна створити власнийпоказник на функцію.
тип (*ім`я_показника_на_функцію) (список_типу_аргументів)
bool (*myfunkPtr) (char, long)
Ця об`ява показника на функцію має логічнезначення і приймає в якості параметрів символ і довге ціле.
При зверненні достатньо вказувати ім`я показника функції;
...
boolbVar;
charSymbol=`X`;
long bNum=15;
bVar=myfunkptr;
19. Посилки в мові с++. Посилка - це особливий тип даних, що є схованою формою показника, який при використанні автоматично розіменовується. Вона може використовуватися, як псевдонім об`єкта.
Приклад
тип &ім`я_посилки=ім`я_змінної;
...
char letter=`A`;
char &ref=letter;
int i=0;
int &ref=i;
ref+=10 //i+=10;
...
Обмеження посилок:
1. Посилку не можна перевизначати.
2. Посилки не можна вказувати на нульовий об`єкт.
20. Варіанти оголошень посилальних параметрів
У виданій в 1986 р. книзі "Язык программирования C++" (у якій був вперше описаний синтаксис мови C++) Б'ярн Страуструп представив стиль оголошення посилальних параметрів, який було схвалено іншими програмістами.
Відповідно до цього стилю оператор "&" зв'язується з іменем типу, а не з іменем змінної. Наприклад, ось як виглядає ще один спосіб запису прототипу функції swap(). void swap(int& x, int& y);
Неважко помітити, що у цьому оголошенні символ "&" прилягає впритул до імені типу int, а не до імені змінної x.
Деякі програмісти визначають в такому стилі і покажчики, пов'язуючи символ "*" з типом, а не із змінною, як у наведеному прикладі:
float* р;
Наведені оголошення відображають бажання деяких програмістів мати у мові програмування C++ окремий тип посилання або покажчика. Але йдеться про те, що таке зв'язування символу "&" або "*" з типом (а не з іменем змінної) не поширюється на весь перелік змінних, які наводяться в оголошенні, що може призвести до плутанини. Наприклад, в наступному оголошенні створюється один покажчик (а не два) на цілочисельну змінну:
int* a, b;
У цьому записі b оголошується як цілочисельна змінна (а не як покажчик на цілочисельну змінну), оскільки, як визначено синтаксисом мови C++, використаний в оголошенні символ "*" або "&" пов'язується з конкретною змінною, якій він передує, а не з типом, за яким його знаходять.
Важливо розуміти, що для С++-компілятора абсолютно байдуже, як саме Ви напишете оголошення: int *p або int* р. Таким чином, якщо Ви вважаєте за краще пов'язувати символ "*" або "&" з типом, а не змінною, то вчиняйте так, як Вам зручно. Але, щоб уникнути надалі будь-яких непорозумінь, у цьому посібнику ми пов'язуватимемо символ "*" або "&" з іменем змінної, а не з іменем типу.