Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Покажчики на багатовимірні масиви

Поиск

Покажчики на багатовимірні масиви в мові СІ - це масиви масивів, тобто такі масиви, елементами яких є масиви. При оголошенні таких масивів у пам'яті комп'ютера створюється кілька різних об'єктів. Наприклад при виконанні оголошення двовимірного масиву int arr2 [4] [3] в пам'яті виділяється ділянка для зберігання значення змінної arr, яка є покажчиком на масив з чотирьох покажчиків. Для цього масиву з чотирьох покажчиків теж виділяється пам'ять. Кожен з цих чотирьох покажчиків містить адресу масиву з трьох елементів типу int, і, отже, в пам'яті комп'ютера виділяється чотири ділянки для зберігання чотирьох масивів чисел типу int, кожен з яких складається з трьох елементів.

Таким чином, оголошення arr2 [4] [3] породжує в програмі три різних об'єкта: покажчик з ідентифікатором arr, безіменний масив з чотирьох покажчиків і безіменний масив із дванадцяти чисел типу int. Для доступу до безіменним масивам використовуються адресні вирази з покажчиком arr. Доступ до елементів масиву покажчиків здійснюється із зазначенням одного індексного виразу у формі arr2 [2] або * (arr2 +2). Для доступу до елементів двовимірного масиву чисел типу int мають бути використані два індексних вираження у формі arr2 [1] [2] або еквівалентних їй * (* (arr2 +1) +2) і (* (arr2 +1)) [2]. Слід враховувати, що з точки зору синтаксису мови СІ покажчик arr і покажчики arr [0], arr [1], arr [2], arr [3] є константами і їх значення не можна змінювати під час виконання програми.

Розміщення тривимірного масиву відбувається аналогічно і оголошення float arr3 [3] [4] [5] породжує в програмі окрім самого тривимірного масиву з шістдесяти чисел типу float масив з чотирьох покажчиків на тип float, масив з трьох покажчиків на масив покажчиків на float, і покажчик на масив масивів покажчиків на float.

При розміщенні елементів багатовимірних масивів вони розташовуються в пам'яті підряд по рядках, тобто швидше за все змінюється останній індекс, а повільніше - перший. Такий порядок дає можливість звертатися до будь-якого елементу багатовимірного масиву, використовуючи адресу його початкового елемента і тільки одне індексне вираз.

Наприклад, звернення до елементу arr2 [1] [2] можна здійснити за допомогою покажчика ptr2, оголошеного у формі int * ptr2 = arr2 [0] як звернення ptr2 [1 * 4 +2] (тут 1 і 2 це індекси використовуваного елемента, а 4 це число елементів в рядку) або як ptr2 [6]. Зауважимо, що зовні схоже звернення arr2 [6] виконати неможливо так як покажчика з індексом 6 не існує.

Для звернення до елемента arr3 [2] [3] [4] з тривимірного масиву теж можнo використовувати покажчик, описаний як float * ptr3 = arr3 [0] [0] з одним індексним вираженням у формі ptr3 [3 * 2 +4 * 3 +4] або ptr3 [22].

Далі приведена функція, яка дозволяє знайти мінімальний елемент в тривимірному масиві. У функцію передається адреса початкового елемента і розміри масиву, повертається значення - покажчик на структуру, яка містить індекси мінімального елемента.

struct INDEX {int i,

int j,

int k} min_index;

struct INDEX * find_min (int * ptr1, int l, int m int n)

{Int min, i, j, k, ind;

min = * ptr1;

min_index.i = min_index.j = min_index.k = 0;

for (i = 0; i * (ptr1 + ind)

{ min=*(ptr1+ind);

min_index.i=i;

min_index.j=j;

min_index.k=k;

} }

return &min_index;

}

Операції з вказівниками

Над покажчиками можна виконувати унарні операції: інкремент і декремент. При виконанні операцій + + і - значення покажчика збільшується або зменшується на довжину типу, на який посилається використовуваний покажчик.

Приклад:

int * ptr, a [10];

ptr = & a [5];

ptr + +; / * одно адресою елемента a [6] * /

ptr -; / * одно адресою елемента a [5] * /

В бінарних операціях додавання і віднімання можуть брати участь покажчик і величина типу int. При цьому результатом операції буде покажчик на вихідний тип, а його значення буде на вказане число елементів більше або менше вихідного.

Приклад:

int * ptr1, * ptr2, a [10];

int i = 2;

ptr1 = a + (i +4); / * одно адресою елемента a [6] * /

ptr2 = ptr1-i; / * одно адресою елемента a [4] * /

В операції віднімання можуть брати участь два покажчика на один і той же тип. Результат такої операції має тип int і дорівнює числу елементів вихідного типу між зменшуваним і вичитав, причому якщо перша адреса молодше, то результат має негативне значення.

Приклад:

int * ptr1, * ptr2, a [10];

int i;

ptr1 = a +4;

ptr2 = a +9;

i = ptr1-ptr2; / * дорівнює 5 * /

i = ptr2-ptr1; / * одно -5 * /

Значення двох покажчиків на однакові типи можна порівнювати в операціях ==,! =, <, <=,>,> = При цьому значення покажчиків розглядаються просто як цілі числа, а результат порівняння дорівнює 0 (брехня) або 1 (істина).

Приклад:

int * ptr1, * ptr2, a [10];

ptr1 = a +5;

ptr2 = a +7;

if (prt1> ptr2) a [3] = 4;

У даному прикладі значення ptr1 менше значення ptr2 і тому оператор a [3] = 4 не буде виконаний.

Питання для контролю:

1. Які є методи доступу до елементів масиву?

2. Що таке покажчики на багатовимірні масиви?

3. Які є операції з вказівниками?

Література:

1. Прата С. Язык программирования С++. Лекции и упражнения. Учебник: Пер. с англ. –СПб.: ДиаСофтЮП, 2003, с. 126-130

 

Урок №63

(згідно робочої навчальної програми)

Тема:Нульові покажчики, покажчики типу void, покажчики і динамічні змінні.

Питання:

1.Робота з покажчиками.

Робота з покажчиками.

У мові С елементи масивів можуть мати будь-який тип, і, зокрема, можуть бути покажчиками на будь-який тип. Розглянемо кілька прикладів з використанням покажчиків.

Наступні оголошення змінних

int a [] = {10,11,12,13,14,};

int * p [] = {a, a +1, a +2, a +2, a +3, a +4};

int ** pp = p;

При виконанні операції pp-p отримаємо нульове значення, так як посилання pp і p дорівнюють і вказують на початковий елемент масиву покажчиків, пов'язаного з покажчиком p (на елемент p [0]).

Результатом виконання віднімання pp-p буде 2, оскільки значення pp є адреса третього елемента масиву p. Посилання * pp-a теж дає значення 2, так як звернення * pp є адреса третього елемента масиву a, а звернення a є адреса початкового елемента масиву a. При зверненні за допомогою посилання ** pp отримаємо 12 - це значення третього елемента масиву a. Посилання * pp + + дасть значення четвертого елемента масиву p тобто адресу четвертого елемента масиву a.

Якщо вважати, що pp = p, то звернення * + + pp це значення першого елемента масиву a (тобто значення 11), операція + + * pp змінить вміст покажчика p [0], таким чином, що він стане рівним значенню адреси елемента a [1].

Складні звернення розкриваються зсередини. Наприклад звернення * (+ + (* pp)) можна розбити на наступні дії: * pp дає значення початкового елемента масиву p [0], далі це значення інкременіруется + + (* p) у результаті чого покажчик p [0] стане дорівнює значенню адреси елемента a [1], і остання дія це вибірка значення за отриманим адресою, тобто значення 11.

У попередніх прикладах був використаний одновимірний масив, розглянемо тепер приклад з багатовимірним масивом і покажчиками. Наступні оголошення змінних

int a [3] [3] = {{11,12,13},

{21,22,23},

{31,32,33}};

int * pa [3] = {a, a [1], a [2]};

int * p = a [0];

Відповідно до цієї схеми доступ до елемента a [0] [0] отримати за вказівниками a, p, pa за допомогою наступних посилань: a [0] [0], * a, ** a [0], * p, ** pa, * p [0].

Розглянемо тепер приклад з використанням рядків символів. Оголошення змінних

char * c [] = {"abs", "dx", "yes", "no"};

char ** cp [] = {c +3, c +2, c +1, c};

char *** cpp = cp;

Питання для контролю:

1. Який тип можуть мати покажчики?

2. Як оголосити вказівник на масив?

3. Як оголосити вказівник на рядок?

Література:

1.Шилдт Г.: Пер. с англ. –М.: Издательский дом “Вильямс”, 2002. –704с. –стор 130-132

Урок №26

(згідно робочої навчальної програми)

Тема: Покажчики і структури даних, покажчики і масиви

Питання:

1. Покажчики на структуру

2. Масиви структур

Покажчики на структуру

Якщо функції передається велика структура, то ефективніше передати покажчик на цю структуру, ніж копіювати її в стек цілком. Покажчик на структуру по виду нічим не відрізняється від покажчиків на звичайні змінні.

Формат: struct point * pp;

де pp - покажчик на структуру типу struct point, * pp - сама структура, (* pp). x і (* pp). y - члени структури.

Дужки (* pp). X необхідні, так як пріоритет операції (.) Вище пріоритету операції (*). У разі відсутності дужок * pp.x розуміється як * (pp.x).

Ініціалізація покажчика на структуру виконується так само, як і ініціалізація вказівників інших типів: struct point var1, * S1; тут var1 - структурна змінна, * S1 - вказівник на структуру.

Для визначення значення покажчика йому потрібно привласнити адресу вже сформованої структури:

S1 = &var1;

Тепер можливо ще одне звернення до елементів структури:

(* S1). Name.

Покажчики на структури використовуються досить часто, тому для доступу до її полях була введена коротка форма запису. Якщо р - покажчик на структуру, то p → <поле структури> зволяет звернутися до зазначеного полю структурної змінної.

Знак → (стрілка) вводиться з клавіатури за допомогою двох символів: '-' (мінус) і '>' (більше). Наприклад, pp → x; pp → y.

Оператори доступу до полів структури (.) І (→) разом з операторами виклику функції () та індексами масиву [] займають найвище положення в ієрархії пріоритетів операцій в мові C.

Покажчики на структуру використовуються у наступних випадках:

- Доступ до структур, розміщеним в динамічній пам'яті;

- Створення складних структур даних - списків, дерев;

- Передача структур в якості параметрів в функції.

Масиви структур

При необхідності зберігання деяких даних у вигляді декількох масивів однієї розмірності, але різного типу, можлива організація масиву структур. Наочно масив структур можна представити у вигляді таблиці, де стовпчики таблиці являють собою поля структури, а рядки - елементи масиву структур.

Наприклад, є два різнотипних масиву:

char c [N];

int i [N];

Оголошення

struct key

{

char c;

int i;

} Keytab [N];

створює тип структури key і оголошує масив keytab [N], кожен елемент якого є структура типу key.

Можливий запис:

struct key

{

char c;

int i;

};

struct key keytab [N];

Ініціалізація масиву структур виконується наступним чином:

struct key

{

char c;

int i;

 

} Keytab [] = {

'A', 0,

'b', 0

};

У цьому прикладі створюється масив на дві структури типу key з ім'ям keytab. Розглянемо звернення до поля структури в цьому випадку - для прикладу виведемо на екран вміст масиву:

for (int i = 0; i <2; i + +)

printf ("% c% d \ n", keytab [i]. c, keytab [i]. i);

При зверненні до поля структури спочатку відбувається звернення до елементу масиву (keytab [i]), а потім тільки звернення до поля структури (keytab [i]. C).

Доступ до поля елемента масиву структур може бути отриманий через константу-покажчик на масив і зміщення всередині масиву, наприклад, доступ до поля елемента масиву з номером i потрібно записати таким чином:

(* (Keytab + i)). C або (keytab + i) → c.

Масив структур також може бути переданий у функцію як аргумент, передача масиву відбувається через покажчик на масив.

Приклад програми, в якій масив точок формується і виводиться на екран за допомогою функцій:

# Include <stdio.h>

# Define N 5

struct point

{int x, y;

};

void form_mas (struct point * mas, int n)

{

printf ("Enter koordinates! \ n");

for (int i = 0; i <n; i + +)

{

printf ("x →");

scanf ("% d", & mas [i]. x);

printf ("y →");

scanf ("% d", & mas [i]. y);}}

void print_mas (struct point * mas, int n)

{printf ("x y \ n");

for (int i = 0; i <n; i + +)

printf ("% 4d% 6d \ n", (mas + i) → x, (mas + i) → y);

}

int main ()

{struct point Points [N];

form_mas (Points, N);

print_mas (Points, N);

return 0;}

Функція form_mas () заповнює масив точок, який переданий у функцію через покажчик mas. Параметр функції n визначає кількість елементів масиву. Доступ до елементу масиву - через операцію. (Крапка). Вираз & mas [i]. X обчислює адресу елемента структури mas [i]. X, так як операція & має нижчий пріоритет, ніж операції [] і • (точка).

Функція print_mas () виводить масив на екран. Передача масиву у функцію відбувається також через покажчик mas. Параметр n - кількість елементів масиву. Доступ до елементу масиву - через операцію → (стрілка).

Питання для контролю:

1.В якому випадку потрібно використовувати показники на структуру?

2. Як оголосити вказівник на структуру?

3.Як організувати масиви структур?

Література:

1.Шилдт Г.: Пер. с англ. –М.: Издательский дом “Вильямс”, 2002. –704с. –стор 132-134

Урок №27

(згідно робочої навчальної програми)



Поделиться:


Последнее изменение этой страницы: 2016-08-10; просмотров: 287; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.151.90 (0.01 с.)