Скачать презентацию Масиви та вказівники в С Проф Куссуль Н Скачать презентацию Масиви та вказівники в С Проф Куссуль Н

Lecture5-CPP.ppt

  • Количество слайдов: 30

Масиви та вказівники в С++ Проф. Куссуль Н. М. 1 Масиви та вказівники в С++ Проф. Куссуль Н. М. 1

Масиви: загальні відомості Масив – тип даних, який використовується для представлення послідовності однорідних значень. Масиви: загальні відомості Масив – тип даних, який використовується для представлення послідовності однорідних значень. Елементи масиву займають одну неперервну область пам’яті комп’ютера і розміщені послідовно один за одним. В С++ можливі масиви будь-яких типів: n n n базових користувацьких масиви масивів тощо 2

Масиви: загальні відомості При оголошенні масиву виділяється пам’ять, починаючи з базової адреси. Ім’я масиву Масиви: загальні відомості При оголошенні масиву виділяється пам’ять, починаючи з базової адреси. Ім’я масиву є постійним вказівником, який ініціалізований цією базової адресою. 3

Приклад int mas 1[492]; // зовнішній масив з 492 елементів void main(void) { double Приклад int mas 1[492]; // зовнішній масив з 492 елементів void main(void) { double mas 2[250]; // масив з 250 чисел типу double static char mas 3[20]; //статичний рядок з 20 символів extern mas 1[]; //зовнішній масив, розмір вказано вище int mas 4[2][4]; // двовимірний масив з чисел типу int } 4

Індексування Нумерація елементів масиву починається з нуля і закінчується n-1 (n - кількість елементів Індексування Нумерація елементів масиву починається з нуля і закінчується n-1 (n - кількість елементів масиву). Доступ до окремого елементу масиву організується з використанням номера цього елементу, або індексу. Нехай int i, a[n]; Доступ a[цілий_вираз]; 5

Індексування Значення індексу поза діапазону викликає помилку виконання. Така ситуація наз. перевищення меж масиву Індексування Значення індексу поза діапазону викликає помилку виконання. Така ситуація наз. перевищення меж масиву або вихід індексу за межі. Ефект від такої помилки в С++ залежить від системи і може бути несподіваним! 6

Ініціалізація масиву означає присвоєння початкових значень його елементам при оголошенні. Масиви можна ініціалізувати списком Ініціалізація масиву означає присвоєння початкових значень його елементам при оголошенні. Масиви можна ініціалізувати списком значень або виразів, відокремлених комою, розташованих у фігурних дужках: n int days[12] = {31, 28, 31, 30, 31, 30, 31}; 7

Ініціалізація масиву Масив також можна ініціалізувати списком без зазначення в дужках довжини масиву. При Ініціалізація масиву Масив також можна ініціалізувати списком без зазначення в дужках довжини масиву. При цьому масиву присвоюється довжина за кількістю ініціалізаторів: n n char code[] = {'a', 'b', 'c'}; в даному прикладі масив code матиме довжину 3 8

Динамічний масив Масив, розмірність якого стає відомою в процесі виконання програми. В С++ для Динамічний масив Масив, розмірність якого стає відомою в процесі виконання програми. В С++ для роботи з динамічними об’єктами використовують спеціальні операції new і delete n n n за допомогою операції new виділяється пам’ять під динамічний об’єкт (який створюється в процесі виконання програми) якщо за допомогою операції new неможливо виділити потрібний об’єм пам’яті, то результатом операції new є 0 за допомогою операції delete створений об’єкт видаляється з пам’яті 9

Приклад Нехай розмірність динамічного масиву вводиться з клавіатури. Спочатку необхідно виділити пам’ять під цей Приклад Нехай розмірність динамічного масиву вводиться з клавіатури. Спочатку необхідно виділити пам’ять під цей масив, а потім створений динамічний масив треба видалити. n int n; cin>>n; // n — розмірність масиву, вводиться з клавіатури int* mas = new int[n]; // виділення пам’яті під масив. . . delete[] mas; // звільнення пам’яті 10

Багатовимірні динамічні масиви Двовимірний масив: створення n n mas=new int[n][k]; // Невірно! Помилка! int** Багатовимірні динамічні масиви Двовимірний масив: створення n n mas=new int[n][k]; // Невірно! Помилка! int** a; //a - вказівник на масив вказівників на рядки a=new int* [n]; //виділення пам’яті для масиву вказівників на n рядків for(int i=0; i

Багатовимірні динамічні масиви Двовимірний масив: знищення n for(int i=0; i<n; i++) delete[] a[i]; //звільнення Багатовимірні динамічні масиви Двовимірний масив: знищення n for(int i=0; i

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

Передача масивів у функції При роботі з рядками (масивами типу char[]), проблема розв'язується просто, Передача масивів у функції При роботі з рядками (масивами типу char[]), проблема розв'язується просто, оскільки останній елемент рядка має значення ''. Наприклад n int length(char c[]) { int i; for(i=0; ; i++) if (c[i]=='') break; return i; } 14

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

Передача масивів у функції Передача з відомим числом елементів int sum(float x[5]) { float Передача масивів у функції Передача з відомим числом елементів int sum(float x[5]) { float s=0; for(int i=0; i<5; i++) s=s+x[i]; return s; } 16

Передача масивів у функції Використання додаткового параметра float max(float a[], int n) { float Передача масивів у функції Використання додаткового параметра float max(float a[], int n) { float m=a[0]; for(int i=1; i

Передача масивів у функції: багатовимірні масиви Особливістю мови С++ є несамовизначеність масивів => за Передача масивів у функції: багатовимірні масиви Особливістю мови С++ є несамовизначеність масивів => за іменем масиву неможливо довідатися про його розмірність і розміри за кожним виміром. Крім того, у С++ багатовимірні масиви не визначені. Наприклад: n n n якщо оголошений масив float d[3][4][5], то це не тривимірний, а одномірний масив d, що включає три елементи, кожний з який має тип float [4][5] в свою чергу, кожний з чотирьох елементів є типу float [5] і, відповідно, кожний з цих елементів є масивом з п'яти елементів типу float. 18

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

Передача масивів у функції: багатовимірні масиви #include <iostream. h> float summa(int n, float a[][3]) Передача масивів у функції: багатовимірні масиви #include float summa(int n, float a[][3]) { float s=0; for(int i=0; i

Передача масивів у функції: багатовимірні масиви #include <iostream. h> float min(int m, int n, Передача масивів у функції: багатовимірні масиви #include float min(int m, int n, float *p[]); void main() { float d[3][4]={1, 2, -2, 4, 5, 0, -3, 18, -9, 6, 7, 9}; float *r[] = { (float*) &d[0], (float*) &d[1], (float *) &d[2] }; int m=3; int n=4; cout <<"n Мінімальний елемент матриці дорівнює "<< min(m, n, r); } float min(int m, int n, float *p[]) { float x=p[0][0]; for (int i=0; ip[i][j]) x=p[i][j]; return x; } 21

Взаємозв’язок між масивами та вказівниками Ім'я масиву являє собою константний (фіксований) вказівник на адресу Взаємозв’язок між масивами та вказівниками Ім'я масиву являє собою константний (фіксований) вказівник на адресу першого (з індексом 0) елемента масиву. Вказівник – це змінна, яка приймає в якості значень адресу. 22

Вказівники Вказівник - це символічне представлення адреси. Він використовується для непрямої адресації змінних і Вказівники Вказівник - це символічне представлення адреси. Він використовується для непрямої адресації змінних і об'єктів. В мові С++ є операція визначення адреси — &, за допомогою якої визначається адреса комірки пам’яті, що містить задану змінну. Наприклад, n якщо vr — ім’я змінної, то &vr — адреса цієї змінної. 23

Вказівники В С++ також існують і змінні типу вказівник. Значенням змінної типу вказівник є Вказівники В С++ також існують і змінні типу вказівник. Значенням змінної типу вказівник є адреса змінної або об'єкта. Нехай змінна типу вказівник має ім'я ptr, тоді в якості значення їй можна присвоїти адресу за допомогою наступного оператора: n int vr; int* ptr; ptr = &vr; 24

Вказівники В мові С++ при роботі з вказівниками велике значення має операція непрямої адресації Вказівники В мові С++ при роботі з вказівниками велике значення має операція непрямої адресації — *. Операція * дозволяє звертатися до змінної не напряму, а через вказівник, який містить адресу цієї змінної. Ця операція є одномісною і має асоціативність зліва направо. n NB Цю операцію не слід плутати з бінарною операцією множення. Нехай ptr — вказівник, тоді *ptr — це значення змінної, на яку вказує ptr. 25

Приклад int a = 5; // оголошення змінної int* p = &a; // p Приклад int a = 5; // оголошення змінної int* p = &a; // p вказує на а int& ref_a = a; // псевдонім для а *p = 7; // значення за адресою p буде дорівнювати 7, тобто а = 7 а = *р + 1; // а стане дорівнювати 8 NB будь-які зміни а рівносильне зміні ref_a! 26

Вказівник і масиви Нехай int mas[4][2]; int *ptr; Тоді вираз ptr=mas вказує на перший Вказівник і масиви Нехай int mas[4][2]; int *ptr; Тоді вираз ptr=mas вказує на перший стовпець першого рядка матриці. Записи mas і &mаs[0][0] рівносильні. Вираз ptr+1 вказує на mas[0][1], далі йдуть елементи: mas[1][0], mas[1][1], mas[2][0] і т. д. ; ptr+5 вказує на mas[2][1]. ptr+1 ptr+2 mas[0][0] mas[0][1] mas[1][0] ptr+3 ptr+4 ptr+5 mas[1][1] mas[2][0] mas[2][1] 27

Посилання (reference) являє собою видозмінену форму вказівника, яка використовується в якості псевдоніму (другого імені) Посилання (reference) являє собою видозмінену форму вказівника, яка використовується в якості псевдоніму (другого імені) змінної. У зв’язку з цим посилання не потребують додаткової пам’яті. Для визначення посилання використовують символ & (амперсант), який ставиться перед змінноюпосиланням. Змінні типу посилання можуть використовуватися для наступних цілях: n n n замість передачі у функцію об’єкта за значенням; для визначення конструктора копії; для перевантаження унарних операцій; 28

Приклад #include <iostream. h> int main() { int t = 13; int &r = Приклад #include int main() { int t = 13; int &r = t; // ініціалізація посилання на t // тепер r синонім імені t 13 cout << "Початкове значення t: " << t; // виводить r += 10; // зміна значення t через посилання cout<<"n Остаточне значення t: " << t; // виводить 23 return 0; } 29

Приклад. Функція з параметром-посилання. #include <iostream. h> void sqr(int &); // прототип функції int Приклад. Функція з параметром-посилання. #include void sqr(int &); // прототип функції int main() { int t = 3; cout << "Початкове значення t: " << t; // виводить 3 sqr(t); cout<<"n. Остаточне значення t: " << t; // виводить 9 return 0; } void sqr(int&x) { x*= x; } 30