Tabele

Uvod

Namesto uvoda si poglejmo naslednji programski primer :

public static void main(String ar[]){


   int a,b,c,d,e,f,g,h,i,j;


   a=1; b=2; c=3; d=4; e=5;
   f=6; g=7; h=8; i=9; j=10;


   System.out.println(a);
   System.out.println(b);
   System.out.println(c);
   // zaradi mazohizma izpuščeno

   b=b+a; c=c+b; d=d+c; e=e+d;
   f+=e; g+=f; h+=g; i+=h; j+=i;

   System.out.println(a);
   // zaradi mazohizma nadaljni izpisi izpuščeni
}
  

Prikazana glavna metoda ne počne nič posebnega : uporabili smo10 celoštevilskih spremenljivk, jih inicializiralii z zaporednimi vrednostmi od 1 do 10, nato nad vsemi opravimi zaporedje enakih operacij: izpis vseh desetih, nato povečanje vseh za vrednost 1 in ponaven izpis vseh desetih spremenljivk.

Dan primer, ki je mimigrede pogost primer v programerski praksi, ne bi bil nič posebnega, če ne bi uporabili desetih spremenljivk. Teh 10 spremenljivk lahko znotraj programa naslovimo le tako, da pri naslavljanju navedemo njihovo ime. V tem poimenskem naslavljanju pa je vzrok naših težav. Postopek, ki ga izvajamo na spremenljivkah je sicer ponovljiv ( za vsako spremenljivko iz nabora spremenljivk izvedi izpis, povečanje in ponoven izpis) vendar zaradi narave uporabljenih deklaracij ponavljanja ne moremo uporabiti.

Primer očitno kaže, da bomo potrebovali drugače organizirane podatke oz. tako njihovo organizacijo, ki bo omogočala izvesti isto operacijo na vseh podatkih z uporabo ponavljanj, po možnosti večkrat, in da bo kljub temu možno v taki organizaciji nasloviti vsak posamezen podatek.

Eno izmed možnosti, kako podatke organizirati na opisan način, podaja mehanizem tabele.

Tabela

Imenovana tudi vektor, polje, array, ..., je kompaktna struktura enega ali več istovrstnih elementov. Ker so vsi elementi v njej iste vrste (tipa), pravimo, da je tabela homogena struktura. Tipično je realizirana tako, da njeni elementi zasedajo zaporedne pomnilniške lokacije:

pomnilniška slika zasedanja pomnilnika
(levo 10 zaporednih deklaracij spremenljivk, desno tabela velikosti desetih elementov).

V primerjavi smo uporabili predpostavko, da imenovane spremenljivke zasedejo zaporedne pomnilniške lokacija, kar pa ni nujno resnično. Zaporednost elementov v tabeli pa je nujno zaradi poenostavitve dostopanja do posameznih elementov, kot si bomo pogledali v nadaljevanju.

Tabele in Java

Tabele v Java so v zasnovi objekti. Dejstvo, da objektov še ne poznamo, nas pri spoznavanju strukture ne bo motilo, ker jo lahko preprosto obravnavamo kot podatkovno strukturo.

Za učinkovito rabo in izkoriščanje tabel je potrebno predstaviti in spoznati naslednje mehanizme:

Deklaracija tabele

Tabelo deklariramo (oz. jo najavimo) tako, da določimo ime tabele, povemo kakšnega tipa bodo (vsi) elementi tabele in uporabimo simbol [], ki pove, da ne gre za spremenljivko enostavnega (primitivnega) tipa, temveč za tabelo:

v splošnem je oblika deklaracije taka:

tipElementovTabele [] imeTabele;

Splošno obliko uporabimo za deklaracijo tabele celoštevilkih vrednosti:

int[] tab;

pri tem tab dejansko ne predstavlja tabele (njenih elementov), temveč predstavlja le referenco oz. pomnilniški naslov tabele tab, ki bo ob rezervaciji prostora za elemente tabele dejansko kazal v pomnilniku na prvi element.

Element tabele je lahko poljuben javanski primitiven tip ali pa poljuben objekt:

char[]   tabelaZnakov;            
double[] tabelaNecelihStevil;   
String[] tabelaNizovZnakov;   

V prvih dveh primerih bodo elementi tabel javanski primitivni tipi, v tretjem objekti.

Notacija deklaracije ni strogo definirana, uporabite lahko katerokoli od spodnjih oblik :

int [] t1; 
int []t2; 
int[] t3; 
int t4[]; 
int[]t5;     

dokler se držite pravila : levo stoji opis tip elementov, desno od tipa sledita označba za tabelo in ime tabele.

Rezervacija prostora za tabelo v pomnilniku

Z rezervacijo prostora dejansko izvršimo pomnilniško rezervacijo za elemente tabele. Pri rezervaciji je potrebno podati število elementov, za katere želimo izvršiti rezervacijo. Pri predpostavki, da imamo deklarirano tabelo celoštevilskih vrednosti tab:

int[] tab;

rezervacijo za deset elementov izvršimo na naslednji način:

tab = new int[10];

Slednji stavek dejansko naredi dvoje :

V primeru, da v pomnilniku ne uspe najti dovolj velikega zveznega področja, referenci priredi vrednost null.

Dva ločena stavka, prvi za najavo (deklaracijo) tabele

int [] tab;

in drugi, za rezervacijo prostora za elemente tabele

tab = new int[10];

ponavadi v programiranju nista običajna praksa. Kar rado se zgodi, da po samostojni deklaraciji pozabimo narediti tabelo (objekt, rezervacijo prostora za elemente tabele). V tem primeru pravimo, da je referenčna spremenljivka tab nereferencirana (ali dereferencirana, vsebuje vrednost null). Referenčne spremenljivke brez objekta na kategera bi kazala ne moremo uporabiti.

Deklaracija z rezervacijo pomnilnika

Razlog, naveden v predhodnem odstavku, je ponavadi zadosten za to, da hkrati z deklaracijo izvršimo todi rezervacijo pomnilniškega prostora. To storimo tako, da prešnja stavka združimo v eno samo vrstico :

int [] tab = new int[10];

pri tem je učinek enak, kot da bi vsak stavek izvršili ločeno. Pomen posameznih delov programskega stavka je enak kot v predhodnem postopnem izvajanju:

Inicializacija tabele

V nasprotju s spremenljivkami (podatki) primitivnih tipov, javanski stroj avtomatično inicializira objektne. V primeru tabele postavi vrednost vseh elementov tabele na vrednost 0. V primeru, da gre za tabelo znakov, jih inicializira z vrednostjo, ki odgovarja ničli; to je z znakom, ki je v kodni tabeli znakov na poziciji 0. Avtomatična inicializacija se izvrši vedno, ko naredimo nov objekt (uporabimo operator new) .

V večini primerov inicializacija, ki jo opravi javanski stroj ne ustreza problemu, ki ga rešujemo. V tem primeru bo pač potrebno napisati ustrezno javansko kodo, ki bo v elemente tabele vstavila tiste vrednosti, ki jih določen trenutek tam želimo. Da pa bi uspešno izvedli take vrste inicializacijo, pa moramo poznati postopek, ki nam omogoča nasloviti posamezne elemente tabele.

Mehanizem naslavljanja posameznih elementov tabele - indeksiranje

V skladu s tabelo

int[ ] tab = new int[10];

      

lahko popišemo naslednje ugotovitve :


Torej mora obstajati mehanizem, s katerim enolično povemo, kateri element naslovimo. Temu mehanizmu enostavno pravimo indeksiranje (indeksiranje v je bistvu določanje vrstnega reda !).

in

indeks predstavlja zaporednao številka elementa v tabeli. Podan je z razdaljo od prvega elementa, na katerega pa kaže referenca tab.

Oblika zapisa se rahlo razlikuje od matematične (tam indekse podpisujemo; npr. ai ), ker se med vrstice pač ne da tipkati. Tako indekse zapisujemo v oglate oklepaje:

 tab[0]  naslovi prvi element tabele
 tab[1]  prvega naslednjega
 tab[4]  pa četrtega 
            

 

Uvodni primer sedaj z uporabe tabele lahko prepišemo na naslednji način :

dolžina dobljene kode ni nič krajša, kot je bila. Vendar mehanizem v spodnjem okvirčku narekuje, da jo je moč izboljšati. Spodnji primer podaja tak del programa :

public static void main(String ar[]){


  int[] tab= new int[10]; 
  int k;

   for (k=0;k<10;k++) 
     tab[k] = k+1;

   for (k=0;k<10;k++)
     System.out.println(tab[k]);         // indeks kot spremenljivka

   for (k=1;k<10;k++) 
     tab[k] += tab[k-1];                 // indeks kot izraz :k+1

   for (k=0;k<10;k++)
     System.out.println (tab[k]);

 } 

 

Rezervacija z inicializacijo

Ali bolje rečeno : deklaracija in rezervacija z inicializacijo

V določenih primerih že imamo nabor vrednosti, s katerimi želimo inicializirati tabelo (recimo, da to zahteva od nas neka programska naloga) ali pa želimo pregram testirati z znanimi vrednostmi elementov tabeli. V takih primerih se lahko poslužimo tudi rezervacije z inicializacijo:

int [] tab = {1,2,3,3,3,3,3,2,1} ;

Predhodno podan stavek pozroči nastanek naslednje tabele :

Pri tem se velikost tabele avtomatično določi iz števila elementov, ki jih naštejemo med zavita oklepaja { }.

 

Lastnost tabele - dolžina

Čeprav je tabela objekt, ki je sam po sebi bolj podatkovna kot objektna struktura, pa kljub temu vsebuje dodatno lastnost, ki opredeljuje število elementov tabele oz. njeno velikost. Lastnost se imenuje length in do nje dostopamo, kot je nakazano v spodnjem primeru:

int [] tab = {1,2,3,3,3,3,3,2,1};

int dolzina = tab.length;

 

 


 

Programske naloge

Naloga 1

Dana je ‘deklaracija’ in ‘rezervacija prostora’ :

 char tab[] = new char[10];

Naloga 2

Glede na dani stavek predhodne naloge, napišite program, ki v prvi in zadnji element vpiše vrednost ‘A’ in vse elemente izpiše na zaslon.

Naloga 3

Napišite program, ki v strukturo, dano v prvi nalogi, vpiše naključno vsebino, generirano iz intervala [’a’.. ’ e’], izpiše vse vrednosti elementov, nato vrednost vsakega elementa zmanipulira tako, da namesto trenutne vsebine vpiše naslednjo črko po abecedi in celotno vsebino še enkrat izpiše.

Naloga 4

Napišite program, ki v tabeli celoštevilskih elementov velikosti 15 elementov poveča vrednost vseh elementov na lihih indeksih za 1.

Naloga 5

Napišite program, ki v tabeli celoštevilskih elementov velikosti 15 elementov poveča vrednost vseh elementov s sodo vrednostjo za 1.