muzruno.com

Какви са динамичните масиви на C ++?

Да определим за начало с какво е динамичен масив. От времето на С има масиви, но характеристиката им е фиксиран размер, който е определен при създаването и не се е променил вече. Поради това те се наричат ​​статични масиви. Очевидно е, че динамичен масив означава, че той може да промени размера си по време на програмата. Също така може да се създаде, когато броят на предполагаемите елементи е дори приблизително неизвестен, т.е. празен.

Управление на динамичната памет

Разпределение на паметта в купчината

Има такова нещо като динамично управление на паметта. Този подход към програмирането ви позволява да използвате паметта на компютъра възможно най-ефективно. В C ++, този процес се контролира от новите операции и операциите за изтриване. Операцията е нова резервна памет в областта на динамичната памет или също така наречена купчина (безплатен магазин или куп на английски език). Съответно операцията за изтриване освобождава резервацията.

Чрез стандартите за програмиране динамичната памет трябва да бъде своевременно наблюдавана и изчиствана, така че нови операции и операции за изтриване често се използват по двойки. Този принцип отдавна е остарял. Корените му се разрастват от времето, когато операционните системи не следят паметта добре, или просто не знаят как да го почистват сами. Сега операционната система винаги изчиства паметта след стартирането на програмата. Изключителното почистване на паметта обаче е знак за добър тон в програмирането.

Операцията е нова резервна памет за обект от определен тип и връща адрес в тази памет. Ако разпределянето на паметта е невъзможно по някаква причина, операцията връща нулев показалец (показалец, който не се отнася до нищо) и изхвърля изключение. Новият оператор работи с обекти от всички типове данни: двоен, char, int и т.н. Разпределението на паметта и нейното изтриване изглежда така.

	int * p = new int- // * - означава, че променливата е показалец. Показателите съхраняват адресите. * P = 9-изтрийте p-

Едномерен масив

Създаването на едномерен динамичен масив е същото като създаването на променлива в купчината.

	двоен * a = нов двоен [10] - // a е показалец към паметта, разпределена на масив от 10 елемента от типа doublea [5] = 2.5-delete [] a- // бъдете внимателни за тази конструкция! Тя е хилава!

След израза за изтриване трябва да посочите квадратни скоби, да определи за програмата предстоящата операция като освобождаване не само на показалеца към масива, но и на самия масив.

Двуизмерен масив

Създаването на едномерен динамичен масив е тривиална задача. И ако имаме нужда от многоизмерна масив ...

	двойно ** ma = ново двойно * [5] - // стъпка 1 за (int I = 0-I < I +) // стъпка 2ma [i] = нова двойна [10] -

По този начин се създава динамичен масив в C ++ с размер от 5 до 10. Това буквално означава, на първата стъпка, да се разпредели масив от 5 елемента в паметта. И след това във втората стъпка разпределянето на паметта за масив от 10 елемента и писането на адреса в него в предишния масив и така за всяка колона.

Двуизмерен динамичен масив

Защо се използва показалец от втора порядък? Това е указание за показалеца. Това е малко трудно за разбиране. Въпреки, че кодът е буквално ни казва да стигнем до всяка стойност се съхранява в масива, трябва да отидете на адреса, за да стигнем до там един адрес, а след това ние ще се стигне до стойност.

Не забравяйте, че дизайнът на паметта за делокация за масива трябваше да се запомни? Двуизмерният масив се унищожава по следния начин.

	за (int I = 0-i < 5l i ++) delete [] ma [i] - // изглежда, че сме забравили нещо,

Сега можете лесно да създадете дори пет-мащабен масив.

Къде е "динамиката"?

В началото се казва, че размерът на динамичния масив се променя по време на програмата, но в горните примери никъде не е посочено изрично. Промените в размерността на масива се правят, като се използва следния алгоритъм:

  1. В паметта се създава нов масив от необходимите размери.
  2. Данните от стария масив се заместват в новия масив.
  3. Старият масив е унищожен.

STL вектор - нов динамичен масив

За да използвате вектори, трябва да се свържете .

Както знаете, стандартната библиотека за шаблони (STL) е оборудвана с набор от контейнери, които управляват колекции от елементи. Сред контейнерите са последователни контейнери. Те се различават предимно при подреждането на елементите чрез време на вмъкване. С други думи, първият елемент винаги ще бъде първият, вторият винаги вторият и т.н. Съществуват и други типове контейнери - асоциативни, подредени по стойността на елементите и изобщо неорганизирани.



Един такъв последователен контейнер е вектор. Управлява елементите на C ++ масива в динамична памет. Достъпът до тези елементи се осъществява директно върху индекса. Поради факта, че векторът е последователен контейнер, добавянето и премахването на елементи се извършва в края на масива и тези операции се извършват много бързо. Но вмъкването на нов елемент в средата или в началото на вектора е много по-бавно, тъй като за да изпълните тази процедура, ще трябва да преместите всички предишни елементи в текущия брой за вмъкване. Да разгледаме един пример.

#include #include int main () {std :: вектор v- // създайте празен вектор за съхранение на елементи от тип int // определението на вектор е шаблон на пространството std, така че std :: for (int i = 0- i <= 5 ++ i) {v.push_back (i) -} за (int i = 0-i < v.size () - ++ i) {std :: cout << v [i] << "," - "std :: cout << std :: endl-system ("пауза") -}

Както можете да видите от кода, работата с вектори е точно същата като с масиви. В този случай векторите са снабдени с полезни допълнителни свойства, като например C ++ функции за динамични масиви .size () и .push_back (). Строго погледнато, тези функции на членовете принадлежат към контейнера.

Добавяне на векторен елемент

Достъп до векторни елементи

Достъпът до векторни елементи е тема, за която трябва да говорите отделно. Има следните начини да се обърнете към елементите на вектора.

V [индекс]

Стандартен референтен индекс

V.at (индекс)

Позовавайки се на елемент по индекс, но ако излезете извън диапазона, се изхвърля изключение

V.front ()

Позовавайки се на първия елемент на вектора

V.back ()

Позовавайки се на последния елемент на вектора

Очевидно е, че най-точният начин за достъп до векторен елемент е да се извика функцията .at (), защото тя генерира изключение от out_of_range, което може да бъде обработено в блока try-catch. Операциите [] и .front () и .back () функционират, ако са извън обхват, работят по непредсказуем начин.

Двуизмерен вектор

Да разгледаме пример за създаване на двумерен динамичен масив C ++ - проста матрица 5 на 5.

Мно-матричната схема
 вектор< вектор > v (5, вектор(5) - v [2] [3] = 10-int a = v [2] [3] -v [2] .Push_back (5) - // създава нов елемент в края на вектора v [ ) - // изтрий последния елемент

Двумерният вектор е вектор на вектори. И с всеки отделен вектор можете да работите: добавете и премахнете елементи, използвайте функциите на членовете, както е показано в примера по-горе в последния ред. Можете също така да използвате iterators. На пръв поглед строителството изглежда плашещо. Но само отначало. Векторите са много по-мощни, отколкото са описани в тази статия. Те могат да бъдат разгледани подробно в документацията.

Изтриване на векторен елемент

заключение

В близкото минало програмистите трябваше сами да създадат динамични масиви, включително всички необходими функции и алгоритми за работа с тях. Но с появата на STL, те могат да използват готови, грижовни и ефективни класове. Следователно не трябва да преоткривате отново колелото, а просто да използвате вектори (или друг подходящ контейнер). И само ако е необходимо, да работи със стари методи.

Споделяне в социалните мрежи:

сроден