Stvaranje dvodimenzionalnog dinamičkog niza u c. Dvodimenzionalni dinamički niz

Obično se količina memorije potrebna za određenu varijablu specificira prije procesa kompilacije deklariranjem te varijable. Ako postoji potreba za kreiranjem varijable čija je veličina unaprijed nepoznata, tada se koristi dinamička memorija. Rezervacija I oslobođenje problemi s memorijom u C++ programima mogu se pojaviti bilo kada. Operacije se provode distribucija pamćenje na dva načina:

  • koristeći funkciju malloc, calloc, realloc I besplatno;
  • preko operatera novi I izbrisati.

Funkcija malloc rezerve susjedni blok memorijskih ćelija za pohranu navedeni objekt i vraća pokazivač na prvu ćeliju ovog bloka. Poziv funkcije izgleda ovako:

void *malloc(veličina);

Ovdje veličina- vrijednost cijelog broja bez predznaka koja određuje veličinu dodijeljenog memorijskog područja u bajtovima. Ako je rezervacija memorije bila uspješna, funkcija se vraća varijabla tipa praznina *, koji se može svesti na bilo koji potrebna vrsta pokazivač.

funkcija - calloc također namijenjen za dodjelu memorije. Unos ispod znači da će biti istaknut br elementi po veličina bajt.

void *calloc(nime, veličina);

Ova funkcija vraća pokazivač na odabrano područje ili NULL kada je nemoguće alocirati memoriju. Posebna značajka funkcije je vraćanje svih odabranih elemenata na nulu.

Funkcija reallocmijenja veličinu prethodno dodijeljena memorija. Obratite joj se ovako:

char *realloc (void *p, veličina);

Ovdje str- pokazivač na memorijsko područje čiju veličinu treba promijeniti veličina. Ako se adresa memorijskog područja promijeni kao rezultat funkcije, tada nova adresaće se vratiti kao rezultat. Ako stvarna vrijednost prvi parametar NULL, zatim funkcija realloc radi isto kao i funkcija malloc, odnosno dodjeljuje memorijsko područje veličine veličina bajt.

Za oslobađanje dodijeljene memorije upotrijebite funkciju besplatno. Obratite joj se ovako:

void free(void *p size);

Ovdje str- pokazivač na memorijsku lokaciju prethodno dodijeljenu funkcijama malloc, calloc ili realloc.

Operatori novi I izbrisati slične funkcije malloc I besplatno. Novi dodjeljuje memoriju, a njegov jedini argument je izraz koji specificira broj bajtova koji će biti rezervirani. Operator vraća pokazivač na početak dodijeljenog memorijskog bloka. Operater izbrisati oslobađa memoriju, njegov argument je adresa prve ćelije bloka koju treba osloboditi.

Dinamički niz- niz promjenjive duljine, memorija za koju se dodjeljuje tijekom izvođenja programa. Dodjela memorije provodi se pomoću funkcija calloc, malloc ili operater novi. Adresa prvog elementa dodijeljene memorijske lokacije pohranjuje se u varijabli deklariranoj kao pokazivač. Na primjer, sljedeća izjava znači da je pokazivač opisan mas te mu se dodjeljuje adresa početka susjednog područja dinamička memorija, istaknuto pomoću operatora novi:

int *mas=novo int;

Količina dodijeljene memorije dovoljna je za pohranu 10 int vrijednosti.

Zapravo, u varijabli mas adresa je pohranjena nulti element dinamički niz. Stoga je adresa sljedećeg, prvog elementa u dodijeljenom memorijskom području mas+1, a mas+i je adresa i-tog elementa. I-tom elementu dinamičkog niza može se pristupiti kao i obično s mas[i] ili na drugi način *(mas +i) . Važno je osigurati da ne prekoračite granice dodijeljenog memorijskog područja.

Kada dinamički niz(u bilo kojem trenutku tijekom rada programa) više nije potreban, tada se memorija može osloboditi pomoću funkcije besplatno ili operater izbrisati.

Predlažem da razmotrite nekoliko zadataka koji pojačavaju ovu lekciju:

Problem 1

Naći zbroj realnih elemenata dinamičkog niza.

//Primjer upotrebe malloc funkcije i besplatno #include "stdafx.h" #include korištenje imenskog prostora std; int main() ( setlocale(LC_ALL,"Rus"); int i, n; float *a; //pokazivač na float float s; cout<<"\n"; cin>>n; //unos veličine niza //dodjela memorije za niz od n realnih elemenata a=(float *)malloc(n*sizeof(float)); cout<<"Введите массив A \n"; //ввод элементов массива for (i=0; i>*(a+i); ) //akumuliranje zbroja elemenata niza za (s=0, i=0; i

//Primjer korištenja funkcija malloc i free

#include "stdafx.h"

#uključi

korištenje imenskog prostora std;

int main()

int i, n;

lebdjeti * a ; //pokazivač na plutanje

plovak s ;

cout<< "\n" ; cin >> n ; //unesite veličinu niza

//dodijeliti memoriju za niz od n realnih elemenata

a = (float * ) malloc (n * sizeof (float ) ) ;

cout<< "Unesite niz A\n";

//ulazni elementi niza

za (i = 0; i< n ; i ++ )

cin >> * (a + i);

//akumulacija zbroja elemenata niza

za (s = 0, i = 0; i< n ; i ++ )

s += * (a + i);

//ispiši vrijednost iznosa

cout<< "S=" << s << "\n" ;

//oslobađanje memorije

besplatno(a);

sustav("pauza");

vratiti 0;

Problem 2

Modificirajte dinamički niz cijelih brojeva tako da njegovi pozitivni elementi postanu negativni i obrnuto. Da bismo riješili problem, pomnožit ćemo svaki element s -1.

//Primjer korištenja operatora new i delete #include "stdafx.h" #include korištenje imenskog prostora std; int main() ( setlocale(LC_ALL,"Rus"); int i, n; //unesite broj elemenata niza cout<<"n="; cin>>n; //dodjela memorije int *a=novo int[n]; cout<<"Введите элементы массива:\n"; //ввод массива for (i=0; i>a[i]; //izbaci navedeni niz za (i=0; i

//Primjer korištenja operatora new i delete

#include "stdafx.h"

#uključi

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "Rus");

int i, n;

//unesite broj elemenata niza

cout<< "n=" ; cin >> n ;

//dodjela memorije

int * a = novo int [n];

cout<< "Unesite elemente niza:\n";

//ulazni niz

Dok sam prikupljao informacije za pisanje ovog članka, sjetio sam se svog prvog poznanstva s pokazivačima - bio sam tako tužan... Stoga, nakon čitanja nekoliko odjeljaka o ovoj temi iz raznih knjiga o programiranju u C++, odlučeno je krenuti drugim putem i predstaviti temu C++ pokazivači redoslijedom kojim smatram potrebnim. Odmah ću vam dati kratku definiciju i pogledat ćemo smjernice na djelu koristeći primjere. Sljedeći članak () opisat će nijanse, upotrebu pokazivača s nizovima u stilu C (nizovi znakova) i glavne stvari koje treba zapamtiti.

Pokazivač u C++ je varijabla koja pohranjuje adresu podataka (vrijednosti) u memoriju, a ne same podatke.

Nakon što pogledate sljedeće primjere, shvatit ćete glavnu stvar - zašto su nam potrebni pokazivači u programiranju, kako ih deklarirati i koristiti.

Recimo da u programu trebamo stvoriti niz cijelih brojeva, čiju točnu veličinu ne znamo prije pokretanja programa. To jest, ne znamo koliko će brojeva korisnik morati unijeti u ovaj niz. Naravno, možemo igrati na sigurno i deklarirati niz od nekoliko tisuća elemenata (na primjer, 5000). To bi (po našem subjektivnom mišljenju) trebalo biti dovoljno za rad korisnika. Da – doista – ovo bi moglo biti dovoljno. Ali nemojmo zaboraviti da će ovaj niz zauzeti puno prostora u RAM-u (5000 * 4 (int tip) = 20000 bajtova). Osigurali smo se, a korisnik će ispuniti samo 10 elemenata našeg niza. Ispada da je zapravo 40 bajtova u upotrebi, a 19.960 bajtova troši memoriju.

nerazumno korištenje RAM-a

#uključi korištenje imenskog prostora std; int main() ( setlocale(LC_ALL, "rus"); const int SizeOfArray = 5000; int arrWithDigits = (); cout<< "Массив занял в памяти " << sizeof(arrWithDigits) << " байт" << endl; int amount = 0; cout << "Сколько чисел вы введёте в массив? "; cin >>iznos; cout<< "Реально необходимо " << amount * sizeof(int) << " байт" << endl; for (int i = 0; i < amount; i++) { cout << i + 1 << "-е число: "; cin >> arrWithDigits[i]; ) cout<< endl; for (int i = 0; i < amount; i++) { cout << arrWithDigits[i] << " "; } cout << endl; return 0; }

#uključi

korištenje imenskog prostora std;

int main()

const int SizeOfArray = 5000 ;

int arrWithDigits [SizeOfArray] = ();

cout<< "Niz zauzet u memoriji"<< sizeof (arrWithDigits ) << " байт" << endl ;

int iznos = 0;

cout<< "Koliko ćete brojeva unijeti u niz?";

cin >> iznos ;

cout<< "Stvarno potrebno"<< amount * sizeof (int ) << " байт" << endl ;

za (int i = 0; i< amount ; i ++ )

cout<< i + 1 << "-е число: " ;

cin >> arrWithDigits [i];

cout<< endl ;

za (int i = 0; i< amount ; i ++ )

cout<< arrWithDigits [ i ] << " " ;

cout<< endl ;

vratiti 0;

Na standardnu ​​funkciju knjižnice veličina() prosljeđivanje deklariranog niza arrWithDigits line 10. Vratit će na mjesto poziva veličinu u bajtovima koju ovaj niz zauzima u memoriji. Na pitanje "Koliko ćete brojeva unijeti u niz?" odgovor je 10. U retku 15, izraz iznos * sizeof(int) postat će ekvivalent 10 * 4, budući da funkcija veličina(int) vratit će 4 (veličina u bajtovima tipa int). Zatim unesite brojeve s tipkovnice i program će ih prikazati na ekranu. Ispada da će preostalih 4990 elemenata pohraniti nule. Zato ih nema smisla pokazivati.

Glavna informacija na ekranu: polje je zauzelo 20.000 bajtova, ali u stvarnosti zahtijeva 40 bajtova. Kako izaći iz ove situacije? Netko će možda htjeti prepisati program tako da korisnik s tipkovnice upisuje veličinu niza i nakon unosa vrijednosti deklarira niz s potrebnim brojem elemenata. Ali to se ne može učiniti bez pokazivača. Kao što se sjećate, veličina niza mora biti konstantna. To jest, cjelobrojna konstanta mora biti inicijalizirana prije deklaracije niza i ne možemo zatražiti njezin unos s tipkovnice. Eksperimentirajte i provjerite.


Ovdje nam operater svijetli crveno >> budući da se konstantna vrijednost ne može mijenjati.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Ovdje smo upozoreni da veličina niza ne može biti vrijednost regularne varijable. Potrebna konstantna vrijednost!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

U sljedećem kodu koristit ćemo pokazivač i operatore koji su vam novi novi(dodjeljuje memoriju) i izbrisati(oslobađa memoriju).

inteligentno korištenje RAM-a pomoću pokazivača

#uključi #uključi korištenje imenskog prostora std; int main() ( setlocale(LC_ALL, "rus"); int sizeOfArray = 0; // veličina niza (unosi korisnik) cout<< "Чтобы создать массив чисел, введите его размер: "; cin >> sizeOfArray; // PAŽNJA! int* arrWithDigits - deklaracija pokazivača // na dio memorije koji će biti alociran new int* arrWithDigits = new int ; za (int i = 0; i< sizeOfArray; i++) { arrWithDigits[i] = i + 1; cout << arrWithDigits[i] << " "; } cout << endl; delete arrWithDigits; // освобождение памяти return 0; }

#uključi

#uključi

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "rus");

int sizeOfArray = 0 ; // veličina niza (unosi korisnik)

cout<< "Da biste stvorili niz brojeva, unesite njegovu veličinu: ";

cin >> sizeOfArray;

// PAŽNJA! int* arrWithDigits - deklaracija pokazivača

// na dio memorije koji će biti dodijeljen pomoću new

int * arrWithDigits = new int [ sizeOfArray ] ;

za (int i = 0; i< sizeOfArray ; i ++ )

arrWithDigits[i] = i+1;

cout<< arrWithDigits [ i ] << " " ;

cout<< endl ;

brisanje arrWithDigits; // oslobađanje memorije

vratiti 0;

Korisnik unosi vrijednost s tipkovnice - linija 12. Pokazivač je definiran u nastavku: int * arrWithDigits Ovaj unos znači da arrWithDigits je pokazivač. Stvoren je za pohranjivanje adrese ćelije u kojoj će se nalaziti cijeli broj. U našem slučaju arrWithDigits pokazat će na ćeliju niza s indeksom 0. Znak * - isto što se koristi za množenje. Na temelju konteksta, prevodilac će "razumjeti" da je ovo deklaracija pokazivača, a ne množenje. Slijedi znak = i operater novi, koji dodjeljuje dio memorije. Sjetimo se da našu memoriju trebamo dodijeliti za niz, a ne za jedan broj. Snimiti novi int [sizeOfArray] može se dešifrirati ovako: novi(dodijeliti memoriju) int(za pohranjivanje cijelih brojeva) (u količini sizeOfArray ).

Tako je u retku 16 definirano dinamički niz. To znači da će memorija za njega biti dodijeljena (ili neće dodijeljena) dok program radi, a ne tijekom kompilacije, kao što se događa s regularnim nizovima. Odnosno, raspodjela memorije ovisi o razvoju programa i odlukama koje se donose izravno u njegovom radu. U našem slučaju to ovisi o tome što korisnik unese u varijablu sizeOfArray

Redak 25 koristi operator izbrisati. Oslobađa dodijeljenog operatera novi memorija. Jer novi dodijeljena memorija za pohranjivanje niza, tada prilikom njegovog oslobađanja trebate jasno dati do znanja prevoditelju da je potrebno osloboditi memoriju niza, a ne samo njegove nulte ćelije na koju se ukazuje arrWithDigits. Stoga, između izbrisati a naziv pokazivača stavlja se u uglaste zagrade brisanje arrWithDigits; Upamtite da svaki put kada se memorija dodjeljuje pomoću novi, trebate osloboditi ovu memoriju pomoću izbrisati. Naravno, kada program završi, memorija koju je zauzeo automatski će se osloboditi. Ali neka vam korištenje operatora postane dobra navika novi I izbrisati u paru sa. Uostalom, program može sadržavati npr. 5-6 polja. A ako oslobodite memoriju svaki put kada više ne bude potrebna u budućnosti u pokrenutom programu, memorija će se koristiti mudrije.

Recimo da smo u našem programu ispunili niz s deset vrijednosti. Zatim smo izračunali njihov zbroj i zabilježili ga u neku varijablu. I to je to - više nećemo raditi s ovim nizom. Program nastavlja raditi iu njemu se stvaraju novi dinamički nizovi za neku svrhu. U ovom slučaju, preporučljivo je osloboditi memoriju koju zauzima prvi niz. Zatim, kada se memorija dodjeljuje za druge nizove, ta se memorija može ponovno upotrijebiti u programu.

Razmotrimo korištenje pokazivača kao parametara funkcija. Za početak upišite i kompajlirajte sljedeći kod. U njemu funkcija prima dvije varijable i nudi promjenu njihovih vrijednosti.

pokušati promijeniti varijable proslijeđene funkciji

#uključi #uključi korištenje imenskog prostora std; void changeData(int varForCh1, int varForCh2); int main() ( setlocale(LC_ALL, "rus"); int varijablaForChange_1 = 0; int varijablaForChange_2 = 0; cout<< "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; cout << endl; changeData(variableForChange_1, variableForChange_2); cout << endl; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; return 0; } void changeData(int varForCh1, int varForCh2) { cout << "Введите новое значение первой переменной: "; cin >> varForCh1; cout<< "Введите новое значение второй переменной: "; cin >> varForCh2; )

#uključi

#uključi

korištenje imenskog prostora std;

void changeData (int varForCh1 , int varForCh2 ) ;

int main()

setlocale(LC_ALL, "rus");

int varijablaZaPromjenu_1 = 0;

int varijablaZaPromjenu_2 = 0;

cout<< "variableForChange_1 = " << variableForChange_1 << endl ;

cout<< "variableForChange_2 = " << variableForChange_2 << endl ;

cout<< endl ;

promjenaPodataka(varijablaZaPromjenu_1, varijablaZaPromjenu_2);

cout<< endl ;

cout<< "variableForChange_1 = " << variableForChange_1 << endl ;

cout<< "variableForChange_2 = " << variableForChange_2 << endl ;

vratiti 0;

void changeData(int varForCh1, int varForCh2)

cout<< "Unesite novu vrijednost za prvu varijablu: ";

cin >> varForCh1 ;

cout<< "Unesite novu vrijednost za drugu varijablu: ";

cin >> varForCh2 ;

Pokrenite program i unesite nove vrijednosti varijable. Kao rezultat, vidjet ćete da se nakon završetka funkcije varijable nisu promijenile i jednake su 0.

Kao što se sjećate, funkcija ne radi izravno s varijablama, već stvara njihove točne kopije. Ove kopije se uništavaju nakon zatvaranja funkcije. Odnosno, funkcija je primila neku varijablu kao parametar, stvorila njezinu kopiju, radila s njom i uništila je. Sama varijabla će ostati nepromijenjena.

Koristeći pokazivače, možemo proslijediti adrese varijabli funkciji. Tada će funkcija moći izravno raditi s varijabilnim podacima na adresi. Unesimo izmjene u prethodni program.

mijenjanje vrijednosti varijabli pomoću pokazivača

#uključi #uključi korištenje imenskog prostora std; void changeData(int* varForCh1, int* varForCh2); int main() ( setlocale(LC_ALL, "rus"); int varijablaForChange_1 = 0; int varijablaForChange_2 = 0; cout<< "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; cout << endl; changeData(&variableForChange_1, &variableForChange_2); cout << endl; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; return 0; } void changeData(int* varForCh1, int* varForCh2) { cout << "Введите новое значение первой переменной: "; cin >> *varForCh1; cout<< "Введите новое значение второй переменной: "; cin >> *varForCh2; )

Svrha predavanja: proučiti deklaracije, dodjelu i oslobađanje memorije za jednodimenzionalne dinamičke nizove, pristup elementima, naučiti rješavati probleme korištenjem jednodimenzionalnih dinamičkih nizova u jeziku C++.

Kada koristite mnogo struktura podataka, često se događa da one moraju imati varijabilnu veličinu ovisno o veličini strukture podataka. vrijeme isporuke programa. U tim slučajevima potrebno je koristiti dinamička dodjela memorije. Jedna od najčešćih takvih struktura podataka su nizovi, u kojima veličina nije inicijalno definirana ili fiksna.

Prema jezični standard Niz je skup elemenata od kojih svaki ima iste atribute. Svi ti elementi smješteni su u susjedna memorijska mjesta u nizu, počevši od adrese koja odgovara početku niza. To jest, ukupni broj elemenata niza i veličina memorije koja mu je dodijeljena potpuno su i jedinstveno određeni definicijom niza. Ali ovo nije uvijek zgodno. Ponekad je potrebno dimenzionirati dodijeljenu memoriju za niz kako bi se riješio određeni problem, a njezina veličina nije unaprijed poznata i ne može se popraviti. Formiranje nizova promjenjivih veličina (dinamičkih nizova) može se organizirati pomoću pokazivača i alata dinamička dodjela memorije.

Dinamički niz je niz čija veličina nije unaprijed fiksna i može se mijenjati tijekom izvođenja programa. Za promjenu veličine dinamički niz programski jezik C++, koji podržava takve nizove, pruža posebne ugrađene funkcije ili operacije. Dinamički nizovi pružaju mogućnost fleksibilnijeg rada s podacima, jer vam omogućuju da ne predviđate pohranjene količine podataka, već da prilagodite veličinu niza u skladu sa stvarno potrebnim količinama.

Deklariranje jednodimenzionalnih dinamičkih nizova

Pod deklaracijom jednodimenzionalnog dinamički niz razumjeti deklaraciju pokazivača na varijablu određenog tipa tako da se ta varijabla može koristiti kao dinamički niz.

Sintaksa:

Upišite *ArrayName;

Tip – tip elemenata koji se deklariraju dinamički niz. Elementi dinamički niz ne mogu postojati funkcije i elementi tip void.

Na primjer:

int *a; dvostruko *d;

U ovim primjerima, a i d su pokazivači na početak dodijeljene memorijske lokacije. Pokazivači uzimaju vrijednost adrese dodijeljenog memorijskog područja za vrijednosti tipa int odnosno tipa double.

Dakle, kada dinamički dodjeljujete memoriju za dinamičke nizove, trebate opisati odgovarajući pokazivač kojem će biti dodijeljena vrijednost adrese početka područja dodijeljene memorije.

Dodjela memorije za jednodimenzionalni dinamički niz

Kako bi se memorija dodijelila jednodimenzionalnom dinamički niz U C++ postoje 2 načina.

1) operacijom new , koji dodjeljuje odjeljak dinamičke memorije odgovarajuće veličine za pohranjivanje niza i ne dopušta inicijalizaciju elemenata niza.

Sintaksa:

ArrayName = new Type [ConstantTypeExpression];

ArrayName – identifikator niza, odnosno naziv pokazivača za dodijeljeni memorijski blok.

TypeExpressionConstant– postavlja broj elemenata ( dimenzija) niza. Izraz konstantnog tipa procjenjuje se u vrijeme prevođenja.

Na primjer:

int *mas; mas = novo int; /*dodijeli dinamičku memoriju od 100*sizeof(int) bajtova*/ dvostruko *m = novo dvostruko [n]; /*dodijeli dinamičku memoriju od n*sizeof(double) bajtova*/ long (*lm); lm = novo dugo; /*dodijeli dinamičku memoriju od 2*4*sizeof(long) bytes*/

Prilikom dodjele dinamičke memorije, dimenzije niza moraju biti u potpunosti navedene.

2) pomoću funkcije knjižnice malloc (calloc) , koji se koristi za dodjelu dinamičke memorije.

Sintaksa:

ArrayName = (Tip *) malloc(N*sizeof(Tip));

ArrayName = (Tip *) calloc(N, sizeof(Tip));

ArrayName – identifikator niza, odnosno naziv pokazivača za dodijeljeni memorijski blok.

Tip – tip pokazivača na niz.

N – broj elemenata niza.

Na primjer:

lebdjeti *a; a=(float *)malloc(10*sizeof(float)); // ili a=(float *)calloc(10,sizeof(float)); /*dodijeli dinamičku memoriju od 10*sizeof(float) bajtova*/

Budući da funkcija malloc(calloc) vraća netipizirani pokazivač void * , tada je potrebno pretvoriti dobiveni

// deklaracija dvodimenzionalnog dinamičkog niza od 10 elemenata:

float **ptrarray = new float* ; // dva retka u nizu

za (int count = 0; count< 2; count++)

ptraniz = novi float; // i pet stupaca

// gdje je ptraniz niz pokazivača na dodijeljeno područje memorije za niz realnih brojeva tipa float

Prvo se deklarira float **ptraarray pokazivač drugog reda, koji se odnosi na niz float* pokazivača, gdje je veličina niza dva . Nakon toga, u for petlji, svaki redak niza deklariran u linija 2 memorija je dodijeljena za pet elemenata. Rezultat je dvodimenzionalni dinamički niz ptraarray. Razmotrimo primjer oslobađanja memorije dodijeljene za dvodimenzionalni dinamički niz.

// oslobađanje memorije dodijeljene za dvodimenzionalni dinamički niz:

za (int count = 0; count< 2; count++)

izbrisati ptrarray;

// gdje je 2 broj redaka u nizu

#uključi
#uključi
#uključi
void main()
{

int *a; // pokazivač na niz

sustav("chcp 1251");

scanf("%d", &n);

scanf("%d", &m);

// Dodjela memorije

a = (int*) malloc(n*m*sizeof(int));

// Unos elemenata niza

za (i=0; i

za (j=0; j

printf("a[%d][%d] = ", i, j);

scanf("%d", (a+i*m+j));

// Elementi izlaznog niza

za (i=0; i

za (j=0; j

printf("%5d ", *(a+i*m+j)); // 5 poznanika za element niza

getchar(); getchar();
}

Rezultat izvršenja

Unesite broj redaka: 3

Unesite broj stupaca: 4

Moguć je i drugi način dinamičke alokacije memorije za dvodimenzionalni niz – pomoću niza pokazivača. Da biste to učinili potrebno vam je:
- dodijeliti blok RAM-a za niz pokazivača;
- dodijeliti blokove RAM-a za jednodimenzionalne nizove, koji su redovi željene matrice;
- upiši adrese linija u niz pokazivača.

Funkcija malloc() vraća pokazivač na prvi bajt memorijskog područja veličine koja je dodijeljena iz dinamički dodijeljenog memorijskog područja. Ako nema dovoljno memorije u području dinamičke memorije, vraća se nulti pokazivač.

#uključi
#uključi
#uključi
void main()
{

int**a; // pokazivač na pokazivač na string

sustav("chcp 1251");

printf("Unesite broj redaka: ");

scanf("%d", &n);

printf("Unesite broj stupaca: ");

scanf("%d", &m);

// Dodjeljivanje memorije za pokazivače na nizove

a = (int**)malloc(n*sizeof(int*));

// Unos elemenata niza

za (i=0; i

// Dodjela memorije za pohranjivanje nizova

a[i] = (int*)malloc(m*sizeof(int));

za (j=0; j

printf("a[%d][%d] = ", i, j);

scanf("%d", &a[i][j]);

// Elementi izlaznog niza

za (i=0; i

za (j=0; j

printf("%5d ", a[i][j]); // 5 poznanika za element niza

slobodan(a[i]); // oslobađanje memorije za niz

getchar(); getchar();
}

Rezultat izvršavanja programa je sličan prethodnom slučaju.

Koristeći dinamičku dodjelu memorije za pokazivače retka, možete dodijeliti slobodne nizove. Besplatno je dvodimenzionalni niz (matrica), čija veličina redaka može biti različita. Prednost korištenja slobodnog niza je u tome što ne morate dodijeliti previše računalne memorije za smještaj niza najveće moguće duljine. Zapravo, slobodni niz je jednodimenzionalni niz pokazivača na jednodimenzionalne nizove podataka.

Pokazivači.

Pokazivač je varijabla čija je vrijednost adresa na kojoj se podaci nalaze. Adresa je broj memorijske ćelije u kojoj ili iz koje se podaci nalaze.

Prema tipu podataka u SI pokazivači se dijele na:

Tipizirani pokazivač je pokazivač koji sadrži adresu podataka određene vrste (sustav ili korisnik).

Netipizirani pokazivač je pokazivač koji sadrži podatkovnu adresu nespecificiranog tipa (samo adresu).

Deklaracija pokazivača;

Postavljanje pokazivača;

pristup vrijednosti koja se nalazi na pokazivaču. Deklaracija (opis) pokazivača u SI jeziku ima sljedeći oblik:

Upišite *ime [=vrijednost];

Kada je deklariran, pokazivač u SI može se inicijalizirati navođenjem odgovarajuće vrijednosti kroz znak dodjele. Ova vrijednost mora biti adresa, napisana u jednom od sljedećih oblika:

Null (id NULL);

Još jedan pokazivač;

Varijabilna adresa (preko operacije uzimanja adrese);

Izraz koji predstavlja aritmetiku pokazivača;

Adresa koja je rezultat dinamičke dodjele memorije.

#uključi

int var; // regularna cjelobrojna varijabla

int *ptrVar; // cjelobrojni pokazivač (ptrVar mora biti tipa int, jer će se odnositi na varijablu tipa int)

ptrVar = // dodijelio pokazivaču adresu memorijske ćelije u kojoj se nalazi vrijednost var varijable

scanf("%d", &var); // varijabla var sadrži vrijednost unesenu s tipkovnice

printf("%d\n", *ptrVar); // izlazna vrijednost putem pokazivača

Rezultat izvršenja: 6 6

Predavanje br.3.

Funkcije.

Funkcija je sintaktički identificirani imenovani programski modul koji izvodi određenu akciju ili grupu akcija. Svaka funkcija ima vlastito sučelje i implementaciju. Sučelje funkcije – zaglavlje funkcije, koje navodi naziv funkcije, popis njezinih parametara i vrstu povratne vrijednosti.

Opis funkcije u SI jeziku provodi se bilo gdje u programu izvan opisa drugih funkcija i sastoji se od tri elementa:

1. prototip funkcije;

2. zaglavlje funkcije;

3. tijelo funkcije.

Prototip funkcije je izborni dio opisa funkcije, namijenjen deklaraciji funkcije čije sučelje odgovara danom prototipu. Deklaracija prototipa ima sljedeći oblik:

Naziv tipa (popis tipova formalnih parametara);

Parametri funkcije su vrijednosti proslijeđene funkciji kada se ona pozove.

Zaglavlje funkcije – opis dijela sučelja funkcije, koji sadrži: tip povratne vrijednosti, naziv funkcije i popis formalnih parametara funkcije. Sintaksa za deklariranje zaglavlja funkcije je:

Naziv tipa (popis formalnih parametara)

Primjeri zaglavlja funkcija:

Int func(int i, dvostruko x, dvostruko y)

Void func(int ind, char *string)

Dvostruka funkcija (void)

Tijelo funkcije je implementacijski dio koji sadrži programski kod koji se izvršava kada se funkcija pozove. Tijelo funkcije uvijek dolazi odmah nakon glave funkcije (ne mogu se odvojiti) i nalazi se u vitičastim zagradama.

Implementacija funkcije u SI za izračunavanje faktorijela broja.

Dvostruki faktorijel (bez predznaka);

Dvostruki faktorijel (broj bez predznaka)

Dvostruka činjenica = 1,0;

For(unsigned i=1;i<=num;i++)

Činjenica *= (dvostruko)i;

Povratna činjenica;

Strukture.

Struktura je složeni tip podataka koji predstavlja skup elemenata različitih tipova poredanih u memoriji. Svaki element u strukturi ima svoje ime i naziva se polje.

Deklaracija u SI strukture izgleda ovako:

Struktura [ime vrste]

Polje_1;

Polje_2;

Polje_N;

) [popis varijabli];

Deklaracija polja strukture moguća je samo bez inicijalizacije. Ako nekoliko polja koja slijede jedno za drugim u opisu strukture imaju isti tip, tada za njihov opis možete koristiti sintaksu za deklariranje nekoliko varijabli istog tipa.

Datoteke.

Datoteka je imenovano područje podataka na nekom mediju za pohranu. Vrste datoteka (u odnosu na SI jezik):
tekst;
binarni.
Osnovne operacije koje se izvode na datotekama:
1.Otvaranje datoteka.
2. Čitanje i pisanje podataka.
3. Zatvaranje datoteka.

Dodatne operacije:
1.Navigacija datotekama.
2. Rukovanje pogreškama pri radu s datotekama.
3.Brisanje i preimenovanje datoteka.
4.Opis varijable

Načini otvaranja datoteke sa SI

Preusmjeravanje streama
DATOTEKA * freopen(const char *ime datoteke, const char *način, DATOTEKA *tok);

Funkcija vraća:
Pokazivač na datoteku - sve je u redu,
NULL – pogreška nadjačavanja.

Zatvaranje datoteke
int fclose(FILE *stream);

Funkcija vraća:
0 – datoteka je uspješno zatvorena.
1 – došlo je do greške pri zatvaranju datoteke.

Kraj provjere datoteke
int feof(DATOTEKA *tok);
stream - pokazivač na otvorenu datoteku.

Funkcija vraća:
0 – ako još nije dosegnut kraj datoteke.
!0 – dosegnut je kraj datoteke.

Otvaranje tekstualnih datoteka
Drugi parametar dodatno specificira znak t (neobavezno):
rt, wt, at, rt+, wt+, at+

Čitanje iz tekstualne datoteke

Formatirano čitanje
int fscanf(FILE *stream, const char * format, ...);

Funkcija vraća:
>0 – broj uspješno pročitanih varijabli,
0 – nijedna varijabla nije uspješno pročitana,
EOF – greška ili kraj datoteke.
Čitanje retka

Funkcija vraća:
tampon - sve je u redu,
Čitanje retka
char * fgets(char * buffer, int maxlen, FILE *stream);

Funkcija vraća:
tampon - sve je u redu,
NULL – greška ili kraj datoteke.
Čitanje simbola
int fgetc(DATOTEKA *tok);
Funkcija vraća:
kod simbola - ako je sve u redu,
EOF – ako je došlo do greške ili je došlo do kraja datoteke.
Vraćanje lika u stream
int ungetc(int c, FILE *stream);
Funkcija vraća:
kod simbola – ako je sve uspješno,
EOF – došlo je do greške.

Pišite u tekst SI datoteka

Formatirani izlaz
int fprintf(FILE *stream, const char *format, ...);
Funkcija vraća:
broj napisanih znakova - ako je sve normalno,
negativna vrijednost – ako postoji greška.
Pisanje niza
int fputs(const char *string, FILE *stream);
Funkcija vraća:
broj napisanih znakova - sve je u redu,
EOF – došlo je do greške.
Napiši simbol
int fputc(int c, DATOTEKA *tok);
Funkcija vraća:
kod snimljenog simbola - sve je u redu,
EOF – došlo je do greške.
Otvaranje binarnih datoteka
Drugi parametar dodatno specificira znak b (obavezno): rb, wb, ab, rb+, wb+, ab+
Čitanje iz binarnih datoteka
size_t fread(void *buffer, size_t size, size_t num,FILE *stream);
Funkcija vraća broj pročitanih blokova. Ako je manji od num, tada je došlo do pogreške ili je došlo do pogreške
kraj datoteke.

Zapisivanje u binarnu datoteku
size_t fwrite(const void *buffer, size_t size, size_t num, FILE *stream);
Funkcija vraća broj zapisanih blokova. Ako je manji od num, tada je došlo do pogreške.

Navigacija datotekama

Čitanje trenutnog pomaka u datoteci:
long int ftell(FILE *stream);
Promjena trenutnog pomaka u datoteci:
int fseek(FILE *stream, long int offset, int origin);

SEEK_SET (0) – od početka datoteke.
SEEK_CUR (1) – od trenutne pozicije.
SEEK_END (2) – od kraja datoteke.
Funkcija vraća:
0 – sve je u redu,
!0 – došlo je do greške.
Prelazak na početak datoteke:
void premotavanje (DATOTEKA *stream);
Čitanje trenutne pozicije u datoteci:
int fgetpos(DATOTEKA *tok, fpos_t *pos);
Postavljanje trenutne pozicije u datoteci:
int fsetpos(DATOTEKA *stream, const fpos_t *pos);
Funkcije vraćaju:
0 – sve je uspješno,
!0 – došlo je do greške.
fpos_t struktura:
typedef struct fpos_t (
dugačak;
mbstate_t wstate;
) fpos_t;

Dobivanje znaka pogreške:
int ferror(FILE *stream);
Funkcija vraća vrijednost različitu od nule ako dođe do pogreške.
Funkcija resetiranja pogreške:
void clearerr(FILE *stream);
Funkcija poruke o pogrešci:
void pogreška(const char *string);

Spremanje u međuspremnik

Funkcija brisanja međuspremnika:
int fflush(DATOTEKA *tok);
Funkcija vraća:
0 – sve je u redu.
EOF – došlo je do greške.
Funkcija upravljanja međuspremnikom:
void setbuf(FILE *stream, char * buffer);

Stvara međuspremnik veličine BUFSIZ. Koristi se prije unosa ili izlaza u tok.

Privremene datoteke

Funkcija stvaranja privremene datoteke:
DATOTEKA * tmpfile(void);
Stvara privremenu datoteku u wb+ modu. Nakon zatvaranja datoteke, potonja se automatski briše.
Funkcija generiranja naziva privremene datoteke:
char * tmpnam(char *buffer);

Brisanje i preimenovanje

Funkcija brisanja datoteke:
int remove(const char *ime datoteke);
Funkcija preimenovanja datoteke:
int rename(const char *fname, const char *nname);
Funkcije vraćaju:
0 – ako je uspješno,
!0 – inače.

Predavanje br.4.

Stog.

Stog je suprotan redu čekanja jer radi po principu zadnji ušao, prvi izašao (LIFO). Da biste vizualizirali hrpu, zamislite hrpu tanjura. Prvi tanjur postavljen na stol koristit će se posljednji, a posljednji tanjur postavljen na vrh bit će korišten prvi. Stogovi se često koriste u sistemskom softveru, uključujući prevoditelje i tumače.

Kod rada sa stekovima glavne su operacije umetanja i dohvaćanja elementa. Ove se operacije tradicionalno nazivaju "push" i "pop". Stoga, da biste implementirali stog, morate napisati dvije funkcije: push(), koja "gura" vrijednost na stog, i pop(), koja "iskače" vrijednost sa stoga. Također morate dodijeliti područje memorije koje će se koristiti kao stog. U tu svrhu možete dodijeliti niz ili dinamički dodijeliti komad memorije pomoću funkcija jezika C predviđenih za dinamičku alokaciju memorije. Kao i kod reda čekanja, funkcija dohvaćanja uzima element s popisa i uklanja ga ako već nije pohranjen negdje drugdje. Dolje je opći oblik funkcija push() i pop() koje rade na nizu cijelih brojeva. Ostale vrste hrpa podataka mogu se organizirati promjenom temeljne vrste podataka niza.

int tos=0; /* vrh hrpe */

/* Gurnite element na stog. */

void push(int i)

if(tos >= MAX) (

printf("Snop je pun\n");

/* Dobivanje gornjeg elementa stoga. */

ako (tos< 0) {

printf("Stog je prazan\n");

povratni stog;

Varijabla tos ("top of stack") sadrži indeks vrha steka. Prilikom implementacije ovih funkcija potrebno je voditi računa o slučajevima kada je stog pun ili prazan. U našem slučaju, predznak praznog stoga je da je tos jednak nuli, a predznak preljeva stoga je da se tos toliko poveća da njegova vrijednost pokazuje negdje iza zadnje ćelije niza.

Primjer rada sa stogom.

Stog će se nalaziti u dinamički dodijeljenoj memoriji, a ne u nizu fiksne veličine. Iako korištenje dinamičke dodjele memorije nije potrebno u tako jednostavnom primjeru, vidjet ćemo kako koristiti dinamičku memoriju za pohranjivanje podataka snopa.

/* Jednostavan kalkulator u četiri koraka. */

#uključi

#uključi

int *p; /* pokazivač na područje slobodne memorije */

int *tos; /* pokazivač na vrh stoga */

int *bos; /* pokazivač na dno hrpe */

void push(int i);

p = (int *) malloc(MAX*sizeof(int)); /* dobivanje memorije za stog */

printf("Greška prilikom dodjele memorije\n");

bos = p + MAX-1;

printf("Kalkulator u četiri koraka\n");

printf("Pritisnite "q" za izlaz\n");

printf("%d\n", a+b);

printf("%d\n", b-a);

printf("%d\n", b*a);

printf("Podijeli s 0.\n");

printf("%d\n", b/a);

case ".": /* prikaži sadržaj vrha hrpe */

printf("Trenutna vrijednost na vrhu stoga: %d\n", a);

) dok(*s != "q");

/* Guranje elementa na stog. */

void push(int i)

if(p > bos) (

printf("Snop je pun\n");

/* Dohvaćanje gornjeg elementa iz hrpe. */

ako (str< tos) {

printf("Stog je prazan\n");

Red.

Red čekanja je linearni popis informacija koje se obrađuju po principu prvi ušao, prvi izašao; ovaj princip (i red kao struktura podataka) ponekad se naziva i FIFO. To znači da će prvi element postavljen u red čekanja biti prvi primljen od njega, drugi postavljeni element će biti uklonjen drugi, itd. Ovo je jedini način rada s redom; nasumični pristup pojedinačnim elementima nije dopušten.

Da zamislimo kako red čekanja radi, predstavimo dvije funkcije: qstore() i qretrieve() (od "store" - "spremi", "retrieve" - ​​​​"primi"). Funkcija qstore() smješta element na kraj reda čekanja, a funkcija qretrieve() uklanja element s početka reda čekanja i vraća njegovu vrijednost. Tablica prikazuje učinak slijeda takvih operacija.

Akcijski Sadržaj reda
qstore(A) A
qstore(B) A B
qstore(C) A B C
qretrieve() vraća A B C
qstore(D) B C D
qretrieve() vraća B C D
qretrieve() vraća C D

Imajte na umu da operacija dohvaćanja uklanja element iz reda i uništava ga osim ako nije pohranjen negdje drugdje. Stoga, nakon što se dohvate svi elementi, red će biti prazan.

U programiranju, redovi se koriste za rješavanje mnogih problema. Jedna od najpopularnijih vrsta takvih zadataka je simulacija. Redovi čekanja se također koriste u planerima zadataka operativnog sustava i u I/O međuspremniku.

/* Mini planer događaja */

#uključi

#uključi

#uključi

#uključi

char *p, *qretrieve(void);

void enter(void), qstore(char *q), review(void), delete_ap(void);

za (t=0; t< MAX; ++t) p[t] = NULL; /* иницилизировать массив

prazni pokazivači */

printf("Ulaz (E), lista (L), brisanje (R), izlaz (Q): ");

*s = vrh(*s);

/* Umetanje novog termina u red čekanja. */

void enter (void)

printf("Unesite termin %d: ", spos+1);

if(*s==0) ​​prekid; /* nije napravljeno snimanje */

p = (char *) malloc(strlen(s)+1);

printf("Nema dovoljno memorije.\n");

if(*s) qstore(p);

/* Pregled sadržaja reda čekanja. */

poništiti pregled (poništiti)

za (t=rpos; t< spos; ++t)

printf("%d. %s\n", t+1, p[t]);

/* Ukloni termin iz reda čekanja. */

void delete_ap(void)

if((p=qretrieve())==NULL) povratak;

printf("%s\n", p);

/* Umetanje sastanka. */

void qstore(char *q)

printf("Popis pun\n");

/* Dohvaćanje termina. */

char *qretrieve(void)

if(rpos==spos) (

printf("Nema više sastanka.\n");

povratak p;

Popis.

Jednostruko povezana ciklička lista je rekurzivna deklaracija struktura, odnosno pokazivač na nju u samoj strukturi tipa:

int podaci;//podatkovno polje

s *sljedeći;//sljedeći element

) *prvi,*curr;//prvi i trenutni element

Inicijalizacija:

prvi->sljedeći=curr;

da biste dobili prvi element koristite first->data

za dodavanje novog elementa: curr->next=new s;

curr=curr->next;//idi na zadnji

i da biste dobili, na primjer, 50. element, prođite kroz listu:

curr=prvi;//idi na prvi

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

if(curr->next!=NULL)

curr=curr->sljedeći;


Povezane informacije.


Prvi put na ovoj web stranici, pa evo.

Novi sam u C++ i trenutno radim na knjizi "Strukture podataka pomoću C++ 2nd ed, D.S. Malik".

U knjizi Malik nudi dva načina za stvaranje dinamičkog dvodimenzionalnog niza. U prvoj metodi varijablu deklarirate kao niz pokazivača, gdje je svaki pokazivač tipa cijeli broj. npr

Int *ploča;

Zatim upotrijebite for-petlju za stvaranje "stupaca" dok koristite niz pokazivača kao "redove".

Druga metoda, koristite pokazivač na pokazivač.

Int**ploča; ploča = novi int* ;

Moje pitanje je: koja je metoda bolja? Lakše mi je vizualizirati metodu **, ali prva se metoda može koristiti na gotovo isti način. Obje metode mogu se koristiti za stvaranje dinamičkih 2-dimenzionalnih nizova.

Uredi: nije bilo dovoljno jasno kao što je gore navedeno. Evo koda koji sam probao:

Int red, stupac; cout<< "Enter row size:"; cin >>redak; cout<< "\ncol:"; cin >>col; int *p_ploča; za (int i=0; i< row; i++) p_board[i] = new int; for (int i=0; i < row; i++) { for (int j=0; j < col; j++) { p_board[i][j] = j; cout << p_board[i][j] << " "; } cout << endl; } cout << endl << endl; int **p_p_board; p_p_board = new int* ; for (int i=0; i < row; i++) p_p_board[i] = new int; for (int i=0; i < row; i++) { for (int j=0; j < col; j++) { p_p_board[i][j] = j; cout << p_p_board[i][j] << " "; } cout << endl; }

4 odgovora

Prva metoda ne može se koristiti za stvaranje dinamičan 2D nizovi jer:

Int *ploča;

u biti ste dodijelili niz od 4 pokazivača na int po hrpi. Dakle, ako sada ispunite svaki od ova 4 pokazivača dinamičkim nizom:

Za (int i = 0; i< 4; ++i) { board[i] = new int; }

ono što na kraju dobijete je 2D niz s statički broj linija (u ovom slučaju 4) i dinamičan broj stupaca (u ovom slučaju 10). Dakle, dinamika nije potpuno, budući da prilikom dodjele niza na stog vi mora naznačiti konstantna veličina, tj. Poznat u vrijeme. Dinamičan niz se zove dinamičan, jer njegova veličina ne mora biti poznata u vrijeme sastavljanja, već se može odrediti nekom varijablom u tijekom izvršenja.

Još jednom kada to učinite:

Int *ploča;

Const int x = 4; //<--- `const` qualifier is absolutely needed in this case! int *board[x];

pružate konstantu poznatu u vrijeme sastavljanja(u ovom slučaju 4 ili x) tako da kompajler sada može unaprijed odabrati ovu memoriju za vaš niz, a kada se vaš program učita u memoriju, on će već imati ovu količinu memorije za niz ploča, zbog čega se zove statički, tj. jer veličina tvrdo kodirano I ne može se dinamički mijenjati(u vrijeme izvođenja).

S druge strane, kada to učinite:

Int **ploča; ploča = novi int*;

Int x = 10; //<--- Notice that it does not have to be `const` anymore! int **board; board = new int*[x];

kompajler ne zna koliko će memorije zahtijevati niz ploča, pa ne zna dodjeljuje unaprijed Svi. Ali kada pokrenete svoj program, veličina niza bit će određena vrijednošću varijable x (u vrijeme izvođenja), a odgovarajući prostor za niz ploča bit će dodijeljen tzv. hrpa- područje memorije u koje se mogu dodijeliti svi programi koji se izvode na vašem računalu unaprijed nepoznata(u vrijeme kompajliranja) sažima memoriju za osobnu upotrebu.

Kao rezultat toga, da biste stvarno stvorili dinamički 2D niz, trebate ići s drugom metodom:

Int**ploča; ploča = novi int*; // dinamički niz (veličina 10) pokazivača na int za (int i = 0; i< 10; ++i) { board[i] = new int; // each i-th pointer is now pointing to dynamic array (size 10) of actual int values }

Upravo smo stvorili kvadratni 2D niz veličine 10 puta 10. Da bismo ga pregledali i ispunili stvarnim vrijednostima, poput 1, mogli bismo upotrijebiti ugniježđene petlje:

Za (int i = 0; i< 10; ++i) { // for each row for (int j = 0; j < 10; ++j) { // for each column board[i][j] = 1; } }

Ono što opisujete za drugu metodu proizvodi samo 1D niz:

Int *ploča = novi int;

Ovo jednostavno dodjeljuje niz s 10 elemenata. Možda ste mislili ovako nešto:

Int **ploča = novi int*; za (int i = 0; i< 4; i++) { board[i] = new int; }

U ovom slučaju, dodjeljujemo 4 int* s, a zatim svaka točka na dinamički alocirano polje od 10 int s.

Sada ovo uspoređujemo s int* pločom; . Glavna razlika je u tome što kada se koristi takav niz, broj "redova" mora biti poznat u vrijeme kompajliranja. To je zato što nizovi moraju imati fiksne veličine vremena kompajliranja. Također možete imati problem ako možda želite vratiti ovo polje iz int* s, budući da će polje biti uništeno na kraju svog opsega.

Metoda koja dinamički dodjeljuje i retke i stupce zahtijeva složenije mjere za izbjegavanje curenja memorije. Memoriju biste trebali osloboditi ovako:

Za (int i = 0; i< 4; i++) { delete board[i]; } delete board;

Umjesto toga preporučujem korištenje standardnog spremnika. Možete koristiti std::array 4> ili možda std::vector > koju inicijalizirate odgovarajućom veličinom.

U oba slučaja, vaša unutarnja dimenzija može se dinamički postaviti (tj. uzeti iz varijable), ali razlika je u vanjskoj dimenziji.

Ovo pitanje je u osnovi ekvivalentno sljedećem:

Je int* x = novo int; "bolji" od int x ?

Odgovor je "ne, osim ako ne morate dinamički odabrati tu veličinu niza."

Ovaj kod dobro radi s vrlo malo zahtjeva za vanjske knjižnice i pokazuje osnovnu upotrebu int **array.

Ovaj odgovor pokazuje da niz svaki ima dinamičku veličinu i također kako dodijeliti linearni niz dinamičke veličine nizu grananja dinamičke veličine.

Ovaj program uzima argumente iz STDIN-a u sljedećem formatu:

2 2 3 1 5 4 5 1 2 8 9 3 0 1 1 3

Kod za program je ispod...

#uključi int main() ( int **niz_nizova; int br_nizova, br_upita; br_nizova = br_upita = 0; std::cin >> br_nizova >> br_upita; //std::cout<< num_arrays << " " << num_queries; //Process the Arrays array_of_arrays = new int*; int size_current_array = 0; for (int i = 0; i < num_arrays; i++) { std::cin >> veličina_trenutnog_niza; int *tmp_array = novi int; za (int j = 0; j< size_current_array; j++) { int tmp = 0; std::cin >>tmp; tmp_niz[j] = tmp; ) niz_nizova[i] = tmp_niz; ) //Obrada upita int x, y; x = y = 0; za (int q = 0; q< num_queries; q++) { std::cin >> x >> y; //std::cout<< "Current x & y: " << x << ", " << y << "\n"; std::cout << array_of_arrays[x][y] << "\n"; } return 0; }

Ovo je vrlo jednostavna implementacija int main i ovisi samo o std::cin i std::cout. Barebone, ali dovoljno dobar da pokaže kako raditi s jednostavnim višedimenzionalnim nizovima.