Kaj so dinamični nizi C ++?

Začnimo z dinamičnim nizom. Od časa Si obstajajo nizi, njihova značilnost pa je bila fiksna velikost, ki je bila zabeležena pri ustvarjanju in se ni več spremenila. Zaradi tega so dobili ime statična polja. Očitno je, da dinamično polje pomeni, da lahko spremeni svojo velikost med programom. Lahko pa se ustvari tudi, ko je število predvidenih elementov celo neznano, prazno.

Upravljanje dinamičnega pomnilnika

Obstaja tak koncept kot dinamično upravljanje pomnilnika. Ta pristop pri programiranju vam omogoča, da kar najbolje izkoristite spomin računalnika. V C ++ ta proces nadzirajo nove in brisanje operacij. Operacija nova rezerva pomnilnika na področju dinamičnega pomnilnika ali tako imenovanega kupa (prosto shranjevanje ali kopičenje v angleščini). V skladu s tem operacija brisanja sprosti rezervacijo.


V skladu s standardi programiranja za dinamični pomnilnik je potrebno spremljati in pravočasno čistiti, tako da se nove in izbrisane operacije pogosto uporabljajo v parih. To načelo je že dolgo zastarelo. Njeni koreni naraščajo od trenutka, ko so bili operacijski sistemi slabo gledani za pomnilnik ali pa preprosto niso vedeli, kako ga sami očistiti. Sedaj operacijski sistem vedno izbriše pomnilnik po zagonu programa. Vendar pa je eksplicitno čiščenje spomina znak dobrega toniranja pri programiranju. Nova operacija zadrži pomnilnik za predmet določene vrste in vrne naslov temu pomnilniku. Če dodelitve pomnilnika iz kakršnega koli razloga ni mogoče izvesti, bo operacija vrnila ničelni kazalec (kazalec, ki nise nanaša na nič) in vrže izjemo. Novi operater deluje s predmeti katere koli vrste podatkov: double, char, int, itd. Dodelitev pomnilnika in njegova odstranitev sta naslednji.




int * p = novo int; //* - pomeni, da je spremenljivka kazalec. Kazalci shranjujejo naslove.
* p = 9;
izbrisati p;

Enodimenzionalna matrika

Ustvarjanje enodimenzionalne dinamične matrike je enako ustvarjanju spremenljivke v kopici.

dvojno * a = novo dvojno 
; //a - kazalec na pomnilnik, dodeljen nizu 10 elementov tipa double
a
= 2,5;
izbrisati [] a; //pozorno si oglejte ta dizajn! Prebrisana je!

Po izjavi brisanja je treba določiti kvadratne oklepaje za označitev prihodnjega delovanja programa kot sprostitev ne le kazalca na matriko, ampak tudi samega niza.

Dvodimenzionalna matrika

Ustvarjanje enodimenzionalnega dinamičnega niza je trivialna naloga. In če potrebujemo večdimenzionalno matriko

dvojno ** ma = novo dvojno * 
; //korak 1
za (int I = 0; I ma [i] = novo dvojno
;

Tako je ustvarjanje dinamičnega niza v C ++ velikosti 5 na 10. Dobesedno to pomeni v prvem koraku porazdeliti v pomnilnik niz 5 elementov, nato pa v drugem koraku dodeliti pomnilnik nizu 10 elementov in pisati naslov na njem v prejšnjem nizu in tako za vsak stolpec. 31]

Zakaj uporabljati kazalec drugega reda? To je kazalec na kazalec. To je malo težko razumeti. Čeprav nam koda dobesedno narekuje, da pridemo do neke vrednosti, shranjene v matriki, moramo iti na naslovtam je še en naslov in potem pridemo do vrednosti.


& lt; skript type = "text /javascript" & gt;
lahko blockSettings2 = {blockId: "R-A-70350-2", renderTo: "yandex_rtb_R-A-70350-2", async:! 0};

če (document.cookie.indexOf ("abmatch ="))> = 0) {
blockSettings2 = {blockId: "RA-70350-2", renderTo: "yandex_rtb_R-A-70350- 2 ", statId: 70350async: 0};
}

Funkcija (a, b, c, d, e) {a [c] = a [c] || [], a [c] .push (funkcija () {Ya .Context.AdvManager.render (blockSettings2)}), e = b.getElementsByTagName ("script") , d = b.createElement ("script"), d.type = "text /javascript", d.src = "//an.yandex.ru/system/context.js", d.async =! 0e.parentNode.insertBefore (d, e)} (to, ta.dokument, "yandexContextAsyncCallbacks");

Ne pozabite, da bi bilo treba spomniti na zasnovo sprostitve pomnilnika za polje? Dvodimenzionalna matrika se uniči na naslednji način.

za (int I = 0; i delete [] ma [i];
//se zdi, da smo pozabili nekaj
izbrisati [] ma; 48]

Zdaj lahko mirno ustvarite celo petdimenzionalni niz.

Kje je "govornik"?

Na začetku je bilo rečeno, da se velikost dinamičnega polja spreminja, medtem ko se program izvaja, vendar v zgornjih primerih Ta sprememba ni bila nikjer eksplicitno navedena, dimenzije spremembe matrike pa so izvedene z naslednjim algoritmom:

  1. V pomnilniku se ustvari novo polje zahtevanih velikosti.
  2. Podatki starega polja so ponovno napisani v novem nizu.
  3. Stari masiv je uničen.

STL vektor - novo dinamično polje

Za uporabo vektorjev se morate povezati.

Kot veste, je standardna knjižnica s predlogami (STL) opremljena z nizom zabojnikov, ki upravljajo zbirke elementov. Posode so zaporedne posode. Razlikujejo se predvsem v urejenosti elementov v času vstavljanja. Z drugimi besedami, prvi element bo vedno prvi, drugi pa vednodrugi itd. Obstajajo tudi druge vrste kontejnerjev - asociativne, urejene po vrednosti elementov in niso v celoti urejene.

En tak zaporedni zabojnik je vektor. Upravlja elemente niza C ++ v dinamičnem pomnilniku. Dostop do teh postavk poteka neposredno z indeksom. Ker je vektor zaporedni vsebnik, se dodajanje in odstranjevanje elementov pojavi na koncu matrike in te operacije se izvedejo zelo hitro. Vendar pa se vstavljanje novega elementa v sredini ali na začetku vektorja pojavi mnogo počasneje, saj bo za ta postopek moral premakniti vse prejšnje elemente na trenutno številko vstavljanja. Razmislite o zgledu.

# vključuje
# vključuje
int main () {
std :: vektor v ; //ustvari prazen vektor za shranjevanje elementov tipa int
//definiranje vektorja je std prostorska predloga, tako da std ::
za (int i = 0; i v.push_back (i);
}
) za (int i = 0; i std :: cout v [i] ";";
}
std :: cout std :: endl;
sistem ("pavza");
}

Kot lahko vidite iz kode, se delo z vektorji izvaja na popolnoma enak način kot pri nizih, medtem ko so vektorji opremljeni z uporabnimi dodatnimi lastnostmi, kot je funkcija C ++ za dinamične matrike. Strogo rečeno, te funkcije pripadajo vsebniku.


& lt; script type = "text /javascript" & gt;
lahko blockSettings3 = {blockId: " RA-70350-3 ", najem erTo: "yandex_rtb_R-A-70350-3", async: 0};

če (document.cookie.indexOf ("abmatch ="))> = 0) {
blockSettings3 = {blockId : "RA-70350-3", renderTo: "yandex_rtb_R-A-70350-3", statId: 70350async:! 0};
}

! funkcija (a, b, c, d, e) {a [c] = a [c] || [], a [c] .push (funkcija () {Ya.Context.AdvManager.render (blockSettings3)} ), e = b.getElementsByTagName ("script") , d = b.createElement ("script"), d.type = "text /javascript", d.src = "//an.yandex.ru/system /context.js ", d.async =! 0e.parentNode.insertBefore (d, e)} (ta, ta.dokument," yandexContextAsyncCallbacks ");

Dostop do vektorskih elementov

Pridobitev dostopa do vektorskih elementov je tema, ki jo je treba obravnavati ločeno. Obstajajo naslednji načini za sklicevanje na elemente vektorja.

V [index]

Standardna referenca po indeksu

V. pri (indeks)

Pritožba na element z indeksom, vendar se izjeme ustvarijo ob izhodu iz območja

V. front ()

Pritožba na prvi element vektorja

V. nazaj ()

Pritožba na zadnji element vektorja

Očitno je, da je najbolj pravilen način za dostop do elementa vektorja, da pokličete funkcijo .at (), ker generira izjemo out_of_range, ki jo je mogoče obdelati v bloku try-catch. Funkcija [] in funkcija .front () .back () delujeta nepredvidljivo, kadar sta izven dovoljenega območja.

Dvodimenzionalni vektor

Razmislite primer ustvarjanja dvodimenzionalnega dinamičnega niza C ++ - preprosta matrika 5 od 5.



vektor & gt; v (5 vektor 
);
v
= 10;
int a = v
;
v
.push_back
; //ustvarimo nov element na koncu vektorja
v
.pop_back (); //izbriše zadnji element

Sorodne publikacije