Programmeerimiskeel C/Massiivid

Allikas: Vikiõpikud

Massiivid[muuda]

Staatiline massiiv[muuda]

Staatilisel kujul on massiiv on terviklik mäluala, millele eraldatakse mälu programmi käivitamise hetkel, mis sisaldab samatüübilisi andmeelemente. Massiivi nimi on programmis samaväärne massiivi algusaadressiga (esimese elemendi aadressiga).

Indeks määrab andmeelemendi massiivis, ehk näitab kohta, mis asub:

massiivi_algusaadress + sizeof(massiivi_andmeelemendi_bitiline_suurus)*indeks.

Lisaks:

  • Massiivi indeks käib nime ees või järgi ümbritsetuna kandiliste sulgudega
  • Massiivi esimene indeks EI OLE 1, vaid on 0.
  • Massiivi parameetrina üle andes, ei anta teda väärtusparameetrina vaid viidaparameetrina, ehk antakse viit massiivi esimese elemendi algusele.

Staatilist massiivi deklareerimine ja väärtustamine[muuda]

Massiivi deklareerimine ja väärtustamine[muuda]

Ühemõõtmelise massiivi ehk vektori deklareerimise üldkuju + näide:

andmetüüp massiivi_nimi[elementide_arv];
int T2isArvud[6];

Deklareeritud massiivi elementide väärtustamine:

T2isArvud[0]=7;T2isArvud[1]=324;T2isArvud[2]=244;// jne.

Massiivi deklareerimine algväärtustamisega[muuda]

Väärtused loendina looksulgudes, eraldajaks koma. Üldkuju ja (2)näidet:

andmetüüp massiivi_nimi[elementide_arv]={väärtus_1,väärtus_2,väärtus_jne,väärtus_n-1,väärtus_n};
int raha[8]={1,2,5,10,25,50,100,500};
int s6na[7]={'Y','L','I','K','O','O','L','\0'};

Lisaks:

  • Algväärtustamise puhul pole vaja määrata maksimaalset indeksit, kuid sellel juhul valitakse selleks algväärtustamiseks vaja läinud elementide arv.
  • Tähemärkide massiivi ehk tekstistringi on võimalik mitut moodi realiseerida. Programmeerimiskeeles C on valitud selleks lahendus :
Teksti pikkust pole otseselt määratud, vaid see sõltub teksit lõpetavast tähemärgist '\0'.
Teksti pikkuse teada saamiseks tuleb otseselt läbi proovida kas järgmine tähemärk lõpetab teksti või mitte - seda teostab funktsioon strlen(); mis asub string.h teegis.

Mitmemõõtmelised massiivid, deklareerimine, väärtustamine[muuda]

Oma olemuselt on mitmemõõtmelised massiivid on massiivide mis omavad mitut dimensiooni. Ehk lihtsalt ühe väärtuse saamiseks vaja täpsustada nii palju indekseid kui on dimensioone.

Näiteks 2-dimensioonilise muutja, ehk maatriksi puhul lisandub üks indeks:

andmetüüp massiivi_nimi[elementide_arv][elementide_arv];
int T2isArvud[6][6];

Deklareeritud massiivi elementide väärtustamine:

T2isArvud[0][0]=7;T2isArvud[0][1]=324;T2isArvud[0][2]=244;// jne.

Lisaks:

  • Mälus on tegemist ikkagi väärtuste loenditega, ning näiteks maatriks m[2][2][2] kuvatakse stiilis:
m[0][0][0], m[0][0][1], m[0][0][2], m[0][1][0], m[0][1][1], m[0][1][2], m[0][2][0], m[0][2][1], m[0][2][2], 
m[1][0][0], m[1][0][1], m[1][0][2], m[1][1][0], m[1][1][1], m[1][1][2], m[1][2][0], m[1][2][1], m[1][2][2], 
m[2][0][0], m[2][0][1], m[2][0][2], m[2][1][0], m[2][1][1], m[2][1][2], m[2][2][0], m[2][2][1], m[2][2][2]
-See jada on eelkõige välja toodud näitamaks, et dimensioonide kasvades tekib palju väärtusi ja suurte dimensiooni indeksite puhul ei pruugi leiduda piisavalt mälu, kuhu terve massiiv mahuks! Et võimalikult effektiivselt mälu hallata, tuleks mälu eraldada dünaamiliselt(vt. dünaamiline mäluhaldus, ... mis pole mõeldud C algajatele).
  • Mitme dimensioonilise massiivi jaoks ei lähe vaja mitme dimensioonilist massiivi(!) vaja läheb vaid: mitme dimensioonilise massiivi indekseid, ühedimensioonilist massiivi ja lisaloogikat.

Massiivi väärtuse läbikäimine[muuda]

Massiivid võimaldavad väärtuste poole pöördumist indeksite kaudu, ning suurendades indeksit on võimalik käia läbi kõik mälu elemendid tsüklis.

Näites kasutame massiivi täitmiseks for-tsüklit, sest deklareeritud massiivi maksimaalne indeks on teada, ning indeksi suurendamine on juba triviaalne juhtum:

//teek sisaldab funktsiooni printf() kirjeldust
#include <stdio.h>

int main(void){
    int m[5], i;

    for (i=0; i<5; i++){  //massiivi indeksid käiakse läbi
        m[i] = i;         //massiivi element väärtustatakse i'ga mis iga kord suureneb
    }

    for (i=0; i<5; i++){  //massiivi indeksid käiakse läbi
                          //ekraanile kuvatakse massiivi sisu
        printf("m[%d] = %d\n", i, m[i]);
    }

    //  Windowsi keskkonnas, kui kavatsed käivitada programmi mitte CMD realt, 
    //  kommenteeri järgmine koodisegmendi rida välja.

    //getchar();getchar();
}

Ning programmi käivitades peaks ilmuma terminali/käsureale:

m[0] = 0
m[1] = 1
m[2] = 2
m[3] = 3
m[4] = 4

Massiivi üleandmine parameeterviidana teisele funktsioonile[muuda]

  1. antakse üle kogu massiiv (näide)
    Siin tuleb tähele panna, et antakse üle kogu massiiv viidana, st. muutuste tegemisel peab arvestama, et muudetakse massiivi olevaid väärtuseid jäädavalt, mitte ainult funktsiooni piires.
  2. antakse üle paar massiivi väärtust (näide)
    Lisade muutuja ette ampersandimärgi(&), loetakse muutujat kui viita selle väärtuse algusele.
    Lisades indekseeritud massiivi ette ampersandimärgi(&), loetakse seda kui viita sellele elemendile.

Lisaks:

  • Nagu näidetest näha on defineeritud konstante, mis määravad massiivi ulatuse. See on vajalik, et mitte sassi ajada mälusolevaid dimensioone, ainult põhidimensioon võib jääda kaudselt määratuks.
  • Koodisegment while(rida-->0){, tähendab: alustatakse kordust, mis kestab kuni rida ei ole enam suurem kui 0, samas pärast igat korda muutuja rida vähendab oma väärtust 1 võrra.

Lisaks[muuda]

Kõrvaldeiagonaal ja peadiagonaal[muuda]

  • Peadiagonaal kujutab endast diagonaali, kus massiivi indeksid on võrdsed:
  • Kõrvaldiagonaal kujutab endast diagonaali, mis on peadiagonaaliga risti.

Näide 2 dimensioonilise maatriksi puhul:

double  M[ ][ ];

M[0][0],M[0][1],M[0][2],M[0][3],
M[1][0],M[1][1],M[1][2],M[1][3],
M[2][0],M[2][1],M[2][2],M[2][3],
M[3][0],M[3][1],M[3][2],M[3][3]

{M[0][0],M[1][1],M[2][2],M[3][3]}  -- peadiagonaal
{M[3][0],M[2][1],M[1][2],M[0][3]}  -- kõrvaldiagonaal

Sõne a la string vs tähemärkide massiiv[muuda]

Siin tuleb tähele panna, et kuigi tegemist on sünonüümidega, et programmeerimiskeeles C's ühel juhul on mõeldakse cahr tüüpi viit ja teisel juhul tähemärkide massiivi.

Näide, kus n on tähemärkide massiiv ja m on viit tähemärkide massiivile.

#include<stdio.h>
#include <string.h>

int main(){
    //deklareerimine
    char *m;
    char n[20];

    //väärtustamine
    m="tere";
    strcpy(n,"tere");

    //kuvamine
    printf("%s\n",m);
    printf("%s\n",n);

    getchar();
    getchar();
}

Tähele tuleks panna:

  1. isegi pärast viida deklareerimist, ei näita ta ühelegi mälu aadressile
  2. viita saab väärtustada nagu stringi: Ning kui seda tehakse, siis sellega luuakse sõne pikkune mäluväli, kuhu väärtus pannakse. Pärast loodud muutuja väärtustamist lisatakse viit antud konstant muutuja esimese tähemärgi algusesse.
  3. kuna massiivid antakse üle viidaparameetritena ja nende ette ei pea & märkima