int *p = new int; //* - означає, що змінна є покажчиком. Покажчики зберігають адреси.
*p = 9;
delete p;
Створення одномірного динамічного масиву відбувається так само, як створення змінної в купі.
double *a = new double[10]; //a - вказівник на пам'ять, виділену під масив з 10 елементів типу double
a[5]= 2.5;
delete[]a; //уважно поставтеся до цієї конструкції! Вона хитра!
Після оператора delete необхідно вказати квадратні дужки, щоб позначити для програми майбутню операцію як звільнення не тільки вказівника на масив, але і сам масив.
Створення одномірного динамічного масиву - тривіальна задача. А якщо нам потрібен багатовимірний масив
double **ma = new double *[5]; //крок 1
for(int I = 0; I < 5; i++) //шаг 2
ma[i]= new double[10];
Таким чином, відбувається створення динамічного масиву в C++ розміром 5 на 10. Буквально це означає на першому кроці виділення в пам'яті масиву з 5 елементів. А потім, на другому кроці, виділення пам'яті під масив з 10 елементів і запис адреси на нього в попередній масив, і так для кожного стовпця.
Чому використовується покажчик другого порядку? Це покажчик на покажчик. Зрозуміти це трохи складно. Хоча код буквально нам говорить, щоб добратися до якого-небудь значення, що зберігається в масиві, нам потрібно пройти за адресою, отримати там ще один адреса і тоді ми вийдемо на значення.
Пам'ятайте про те, що конструкцію звільнення пам'яті для масиву потрібно було запам'ятати? Двовимірний масив знищується наступним чином.
for(int I = 0; i < 5l i++)
delete[]ma[i];
//здається, ми щось забули
delete[]ma;
Тепер можете спокійно створити навіть пятимерный масив.
На початку було сказано, що розмір динамічного масиву змінюється під час роботи програми, але в прикладах вище ніде цього явно вказано не було. Зміни розмірності масиву виробляються за наступним алгоритмом:
Для використання векторів необхідно підключити .
Як відомо, стандартна бібліотека шаблонів (STL) забезпечена набором контейнерів, які керують колекціями елементів. Серед контейнерів є послідовні контейнери. Вони відрізняються головним чином впорядкованістю елементів за часом вставки. Іншими словами, перший елемент завжди буде першим, другий завжди другим і т. д. Є й інші види контейнерів – асоціативні, впорядковані за значенням елементів і неврегульовані зовсім.
Одним з таких послідовних контейнерів є вектор. Він керує елементами масиву C++ в динамічній пам'яті. Доступ до цих елементів здійснюється безпосередньо за індексом. Завдяки тому, що вектор – послідовний контейнер, додавання і видалення елементів відбувається в кінці масиву, і ці операції виробляються дуже швидко. Проте вставка нового елемента в середину або початок вектора відбувається значно повільніше, оскільки для здійснення цієї процедури доведеться перемістити всі попередні елементи до поточного номера вставки. Розглянемо приклад.
#include
#include
int main() {
std::vector v; //створення порожнього вектора для зберігання елементів типу int
//визначення вектора – шаблон простору std, тому std::
for(int i = 0; i <= 5; ++i) {
v.push_back(i);
}
for(int i = 0; i < v.size(); ++i) {
std::cout v[i]", ";
}
std::cout std::endl;
system("pause");
}
Як видно з коду, робота з векторами здійснюється точно так само, як з масивами. При цьому вектори забезпечені корисними додатковими властивостями, такими як функції З++ для динамічних масивів .size ().push_back(). Строго кажучи, дані функції-члени належать контейнера.
Отримання доступу до елементів вектора – це тема, про яку варто поговорити окремо. Існують наступні способи звернутися до елементів вектора.
V[index] | Стандартне звернення за індексом |
V. at(index) | Звернення до елементу з індексом, але при виході за межі діапазону генерується виключення |
V. front() | Звернення до першого елементу вектора |
V. back() | Звернення до останнього елемента вектора |
Очевидно, що найбільш вірним способом звернення до елементу вектора є виклик функції .at(), так як вона генерує виняток out_of_range, яке можна обробити в блоці try-catch. Операція[]і функції .front ().back() у разі виходу за межі допустимого діапазону працюють непередбачуваним чином.
Розглянемо приклад створення двовимірного динамічного масиву С++ - простий матриці 5 на 5.
vector < vector > v(5 vector (5));
v[2] [3]= 10;
int a = v[2] [3];
v[2].push_back(5); //створення нового елемента в кінець вектора
v[2].pop_back(); //видалення останнього елемента