Приклад
void main()
{
int *b; //Створюємо вказівник b b = main *b = 1224
*b = 2; // Така вказівка небезпечна, так як пам’ять під *b не виділено
// b = main *b = 2
b = new; //Створюємо динамічну змінну в купі. Вказівник b містить її адресу
//b = 9131:0004 *b = 27966
*b = 5; // Змінюємо значення динамічної змінної b = 9131:0004 *b = 5
delete b; //Знищуємо динамічну змінну, на яку вказує b (вивільняємо
//динамічну пам’ять)
b = 0; //Занулюємо вказівник b b = NULL *b =4200
}
При створенні вказівника b (int *b) він вказує на деяку випадкову змінну (зі значенням 1224). Після занулення його, він теж вказує на деяку іншу випадкову змінну (зі значенням 4200)
Висновок:
1. Якою б не була змінна, вона замає в пам’яті деяку ділянку, яка має адресу. Адреса складається з двох значень, що визначають адресу сегмента та зміщення.
2. «Взяти» адресу можна за допомогою команди &.
3. Значенням вказівної змінної є адреса деякої іншої змінної.
4. Змінні поділяються на:
- статичні (до неї можна звернутися як по адресі – через деякий вказівник, так і по імені)
- динамічні (вони імені не мають, до них можна звернутися лише по адресі, тобто через деякий вказівник).
5. Динамічна змінна розміщена в динамічній пам’яті – в купі, статична – в статичній.
6. Динамічну змінну можна створити командою new та знищується командою delete в довільній точці програми.
3. Нетипізовані вказівні змінні.
Розглядаючи динамічні змінні та змінні-вказівники, ми описували вказівник на деяку динамічну змінну наприклад цілого типу так: int *a, де а – вказівник на деяку динамічну змінну цілого типу. Значенням змінної-вказівника є адреса динамічної змінної, цілого типу.
Але, оскільки адреси як змінних цілого типу, так і змінних інших типів мають один і той же формат (складаються з пари чисел, представлених у 16-вій системі), то очевидно одна і та ж вказівна змінна може містити як адресу динамічної змінної цілого типу, так і адресу динамічної змінної довільного іншого типу. Такі змінні-вказівники називаються нетипізованими.
При описі нетипізованої вказівної змінної замість типу вказується службове слово void.
Наприклад, запис void *a означає, що вказівник а може містити адресу деякої динамічної змінної довільного типу.
Тема. Динамічні масиви . Створення і використання динамічних масивів. Вказівники і стрічки.
План
1. Динамічні масиви .
2. Створення і використання динамічних масивів.
3. Вказівники і стрічки.
.1 Динамічні масиви .
В С++ існує зв'язок між вказівниками і масивами, і зв'язок дуже тісний . Будь-який доступ до елемента масиву, який здійснений операцією індексації, може бути виконаний за допомогою вказівника. Варіант з вказівниками в загальному випадку працює швидше, але розібратися в ньому досить важко.
Оголошення
int а[10]; визначає масив а розміру 10, тобто блок з 10 послідовних об'єктів з іменами а[0], а[1] ..., а[9].
Запис а[i] посилає нас до i-го елемента масиву. Якщо pa є вказівник на int, тобто оголошений як int *pa; то в результаті присвоєння pa = &a[0]; pa вказуватиме на нульовий елемент а, інакше кажучи, pa міститиме адресу елемента а[0]. Тепер
присвоєння x = *pa; копіюватиме вміст а[0] в x. Якщо pa указує на деякий елемент масиву, то pa+1 за визначенням вказує на наступний елемент, pa+i - на i-й елемент після pa, а pa-i - на i-й елемент перед pa. Таким чином, якщо pa вказує на а[0], то
*(pa+1) є вміст а[1], a+i - адреса а[i], а *(pa+i) - вміст а[i].
Зроблені зауваження вірні незалежно від типу і розміру елементів масиву а. Значення слів "додати 1 до вказівника", як і значення будь-якої арифметики з вказівниками, полягає в тому, щоб pa+1 вказував на наступний об'єкт, а pa+i - на i-й після pa.
Між індексацією і діями з покажчиками існує дуже тісний зв'язок. За визначенням значення змінної або вирази типу масив є адреса нульового елемента масиву. Після присвоєння pa = &a[0]; ра і а мають одне і те ж значення. Оскільки ім'я масиву є синонімом розташування його початкового елемента, присвоєння pa=&a[0] можна також записати в наступному вигляді:
pa = а;
Але а[i] можна записати як *(a+i). Обчислюючи а[i], С++ відразу перетворить його в *(a+i); вказані дві форми запису еквівалентні. З цього виходить що отримані в результаті вживання оператора & записи &a[i] і a+i також будуть еквівалентними, тобто і в тому і в іншому випадку це адреса i-го елемента після а. З другого боку, якщо pa - вказівник, то його можна використовувати з індексом, тобто запис pa[i] еквівалентний запису *(pa+i). Коротше кажучи, елемент масиву можна зображати у як вигляді вказівника із зсувом, так і у вигляді імені масиву з індексом.
Між ім'ям масиву і вказівником, виступаючим в ролі імені масиву, існує одна відмінність. Вказівник - це змінна, тому можна написати pa=a або pa++. Але ім'я масиву не є змінним, і записи на зразок a=pa або a++ не допускаються.
.2 Створення і використання динамічних масивів.
Під час компіляції програмного коду для статично оголошених масиві нкадається пам’ть. Для ефективного використання пам’ті призначене динамічне оголошення масивів, а саме:
<тип вказівника> *<назва> = <тип змінної> [<кількість>];
Звичайний статичний масив – це сукупність послідовно розташованих комірок пам’яті.
Динамічний масив – це неперервна ділянка пам’яті розміром sizeof(тип змінної)*<кількість>
Щоб вивільнити пам’ять з-під динамічного масиву користуються командою
delete [ ]<назва вказівника на масива>
З динамічним масивом працювати аналогічно як і з звичайним масивом. Перевага динамічного масиву полягає в тому, що пам’ять з під динамічного масиву можна вивільнити в довільній точці програми. Крім того при оголошенні динамічного масиву в якості його розміру можна вказати попередньо ініціалізовану деяку змінну. Тобто розмір масиву визначатиметься не на етапі компіляції, а на етапі роботи програми (приклад2).
Динамічні масиви використовуються тоді, коли необхідно опрацьовувати кілька великих масивів, для одночасного збереження яких пам’яті не вистачає. Тоді створюють перший динамічний масив. Опрацьовують його, знищують, а тоді створюють наступний масив….
Дата добавления: 2015-08-26; просмотров: 882;