понедељак, 05. октобар 2015.

Nizovi u C++ programskom jeziku


Najjednostavnije definisano; niz je niz promenjivih istog tipa koji se nalaze u memoriji. Možemo reći i da je niz kolekcija elemenata ili lokacija za smeštanje podataka istog tipa. Inače niz predstavlja proizvoljno veliku količinu podataka indeksiranih sa brojevima. Sa malo koda vi u suštini pravite strukture nizova podataka proizvoljnih dimenzija, zatim pomoću petlji možete efikasno da obrađujete strukture podataka. Nizovi skoro uvek idu zajedno sa petljama i zbog toga su veoma korisni. Međutim nizovi u C++ programskom jeziku nisu baš kao u C# programskom jeziku jer su nizovi u C# objekti i moraju se instancirati što nije slučaj u C++ programskom jeziku. C++ programski jezik nije garbage collected i upotreba ključne reči new zahteva ručno oslobađanje memorije. Ali sad da ne komplikujem nego da pojednostavimo.


( Arrays, jednodimenzionalni i dvodimenzionalni nizovi )

Nizovi se deklarišu prvo određivanjem tipa niza, zatim imenom niza i veličinom. Najjednostavnija sintaksa niza je:

tip ime_niza [veličina];

Takođe o nizovima treba da znate da u niz možete smestiti i stringove i objekte i druge nizove ali u svakom nizu može da postoji samo isti tipovi podataka. Npr. Ovako se definiše niz koji sadrži 10 promenjivih tipa integer.

int numbers[10];


Sad u niz numbers možete staviti 10 brojeva tipa integer umesto da pravite 10 promenjivih:

numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
numbers[5] = 6;
numbers[6] = 7;
numbers[7] = 8;
numbers[8] = 9;
numbers[9] = 10;

Međutim ovako dodeljivanje nema neke velike razlike u pisanju 10 promenjivih tipa integer sa dodeljenim vrednostima. Zato isti niz možemo napisati, deklarisati i dodeliti nizu vrednosti jednostavnije; u jednoj liniji koda pomoću agregata jednostavnom notacijom vitičasti zagrada i tačka zarezom. 

int numbers[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Ovako u jednoj liniji koda vi vršite i pravilno inicijalizaciju. Inače bez inicijalizacije niza vaš program vam može praviti komplikacije; ukoliko niste deklarisani niz na globalnom nivou. C++ programski jezik na žalost automatski inicijalizuje promenjive i sve elemente niza nulom samo na globalnom nivou. Što u prevodu znači da promenjive i svi elementi deklarisani na lokalnom nivou sadrže slučajne vrednosti (smeće). Ovako kompajler može da obradi vaš niz kao da to nije ni bitno ali može i da vam napravi ogromne komplikacije.

Kako to misliš, da mogu imati komplikacije kad deklarišem niz bez inicijalizacije?


Pogledajte ovaj kod koji prikazuje na ekranu šta sadrže integer promenjive u nizu numbers kad niz nije inicijalizovan i kad je deklarisan na nivou main() funkcije; što znači da niz nije deklarisan na globalnom nivou.

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
       int brojevi[10];
      
       for (int i = 0; i < 10; i++)
       {
             cout << brojevi[i] << endl;

       }

       cout << endl;
       system("PAUSE");
       return 0;

}

Kad pokrenete program rezultat nisu nule već slučajni brojevi. To ponekad ume da kompromituje kompajler i napravi druge nepredviđene komplikacije iako vam kompajler ne prijavljuje grešku tokom pisanja koda.

-858993460

-858993460

-858993460

-858993460

-858993460

-858993460

-858993460

-858993460

-858993460

-858993460

Press any key to continue . . .


Ukoliko pomerite deklaraciju iznad main() funkcije, rezultat će biti nule. Zato koristite inicalizaciju kad god su vam poznate vrednosti ili definišite niz na globalnom nivou. Ako koristite moderniji kompajler koji podržava standard C++ 11, možete i da koristite i std::array kontajner. To je kontejner za reprezentaciju nizova konstantne dužine. Dizajniran je da omogućava standardne operacije nad kontejnerima, sam niz zna svoju veličinu, ima iteratore, ima operatore dodele i poređenja i drugo što vam može biti od velike koristi ukoliko obrađujete komplikovane operacije na nizom. Pogledajte kako sa std::array kontejnerom jednostavno sortirate brojeve u nizu: 

#include "stdafx.h"
#include <iostream>
#include <array>
using namespace std;

int main()
{
       array<int, 10>numbers = { 1, 7, 3, 10, 5, 2, 6, 8, 9, 4 };
       sort(numbers.begin(), numbers.end());
      
       for (int i = 0; i < 10; i++)
       {
             cout << numbers[i] << endl;

       }

       cout << endl;
       system("PAUSE");
       return 0;

}

Kad pokrenete program celi niz brojeva će automatski biti sortiran.

1
2
3
4
5
6
7
8
9
10

Press any key to continue . . .


Još bih dodao ukoliko niste primetili, indeksiranje niza uvek počinje od nule. Često i najveći broj bagova se dešava što programeri na momenat zaborave da veličina niza i sadržaj elementa nisu isto. Ovde je prikazana veličina niza 10.
int numbers[10];

To nije broj elemenata niza. U ovom nizu ne postoji broj elementa 10. Najveći broj elementa je uvek manji za 1 od veličine niza, zato što indeksiranje niza počinje od nule.

numbers[9] = 10;

Mnogi programeri koji su radili sa programskim jezicima koji vrše indeksiranje od 1 i oni se često pitaju; Zašto u C programskim jezicima indeksi počinju od nule? Zato što se na mašinskom nivou indeksiranje vrši putem pomeranja. Memorijska lokacija na samom procesoru sadrži adresu prvog elementa dok drugi sadrži pomeranje, udaljenost do željnog elementa. Tako programski jezici poput FORTAN-a koji indeksiraju elemente niza od 1, se na mašinskom nivou prvo moraju pretvoriti u nizove čiji indeksi počinju od 0. To se radi oduzimanjem svakom indeksa za 1. Kod C programski jezika kompajler ne mora da vrši oduzimanje, ali zato mi moramo da prihvatimo da indeksiranje počinje od 0.

Takođe, ukoliko ne znate koliko podataka će te smestiti u niz, jednostavno ne određujete veličinu niza:

int numbers[];
 
Da li C++ programski jezik podržava višedimenzionalne nizove? 

Naravno da podržava, jer čak i C programski jezik podržava višedimenzionalne nizove. Što se tiče višedimenzionalni nizova najčešće ćete koristiti dvodimenzionalne nizove, osim ako ne programirate igrice i često radite sa matricama. Višedimenzionalne nizove često zovu i niz nizova. Sintaksa je slična jednodimenzionalnom nizu.

tip ime_niza [veličina] [veličina] [veličina] … ;

Ovako se na primer deklariše dvodimenzionalan niz koji će na primer predstavljati šahovsku tablu.

int chessboard[8][8];


I za višedimenzionalne nizove važi ista pravila kao i za jednodimenzionalne, samo obratite pažnju ako je niz deklarisan na globalnom nivou, onda je u C++ programskom jeziku inicijalizovan na nule inače nije. Da bi smo inicijalizovali višedimenzionalni niz u proceduri main() i sve elemente postavili na nultu vrednost, onda to možemo uraditi ovako:

#include "stdafx.h"
#include <iostream>
#include <array>
using namespace std;

int main()
{
       int chessboard[8][8];
            
       for (int i = 0; i < 8; i++)
       {
             for (int j = 0; j < 8; j++)
             {
                    chessboard[i][j] = 0;
                    cout << chessboard[i][j] << "\t\t";

                    if (j % 2 == 1) cout << endl;

             }
       }

       cout << endl;
       system("PAUSE");
       return 0;

}

Kad pokrenete ovaj program, videćete da su svi elementi šahovske table inicijalizovani na 0.

. . .

0         0
0         0
0         0
0         0
0         0

Press any key to continue . . .


Kod šahovske table, vama je poznato da imate 64 kvadrata, ali kod složeniji nizova gde recimo neka polja neće nikad ni biti upotrebljena, programerska cena memorije postaje skupa. Kad deklarišete niz vi kažete kompajleru koliko objekata želite da smestite u njega, kompajler odvaja memoriju i za elemente koje ne koristite. U takvim situacijama je neophodno da koristite naprednije strukture podataka i pokazivače. Pogledajte kako najjednostavnije možete smestiti tablicu množenja u dvodimenzionalni niz.


#include "stdafx.h"
#include <iostream>
using namespace std;

int multipletable[10][10];

int main()
{
      
       for (int i = 1; i <= 10; i++)
       {
             for (int j = 1; j <= 10; j++)
             {
                    multipletable[(i - 1)][(j - 1)] = i * j;
      
             }
       }
      
       for (int k = 0; k < 10; k++)
       {
             for (int l = 0; l < 10; l++)
             {
                    cout << multipletable[k][l] << "\t";

             }
       }
      
       cout << endl;
       system("PAUSE");
       return 0;

}

Pokretanjem ovog programa dobićete tablicu množenja smeštenu u dvodimenzionalni niz: 

1    2    3    4    5      6    7    8     9   10
2    4    6    8   10  12   14   16  18   20
3    6    9  12   15  18   21   24  27   30
4    8  12  16   20  24   28   32  36   40
5  10  15  20   25  30   35   40  45   50
6  12  18  24   30  36   42   48  54   60
7  14  21  28   35  42   49   56  63   70
8  16  24  32  40   48   56   64  72   80
9  18  27  36  45   54   63   72  81   90
10 20 30  40  50   60   70   80  90 100

Press any key to continue . . . 


Kako to sve izgleda možete pogledati i na video-u:




 

( C++ Tutorial - 7. Arrays )