Dvodimenzioni nizovi (matrice) u jeziku C

Lekcija 10 od 15 · C

Dvodimenzionalni nizovi, ili matrice, predstavljaju ključni koncept u C programiranju, omogućavajući efikasno skladištenje i manipulaciju podacima u tabelarnom formatu. Na ovoj stranici ćete pronaći sveobuhvatan uvod u rad sa dvodimenzionalnim nizovima u C jeziku, uključujući deklaraciju, inicijalizaciju i praktične primere koji demonstriraju njihovu primenu u raznovrsnim situacijama.

Pretpostavimo da želimo da ispišemo niz od prvih 100 prirodnih brojeva, ali da budu ispisani u 10 redova i 10 kolona, kao na slici ispod:

Matrični prikaz 100 brojeva u 10 redova

Da bi smo ovo ispisali koristimo ugnježdenu for petlju:

#include <stdio.h>
int main() {
    // Popunjavanje matrice i ispis elemenata
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            // Računanje vrednosti elementa
            int a = 10 * i + (j + 1);

            // Ispis elementa sa dva mesta širine
            printf("%4d ", a);
        }

        // Novi red nakon svakog reda matrice
        printf("\n");
    }

    return 0;
}

Da bi ove brojeve stavili u memoriju, morali bi smo da uvedemo ili 10 nizova po 10 elemenata ili ako želimo da sve podatke upamtimo u jednoj promenljivoj, onda bi upotrebili dvodimenzioni niz(matricu)

int matrica[ 10 ][ 10 ] ;

Ovo je matrica celih brojeva koja ima 10 redova i 10 kolona.

Pristup određenom elementu koji se recimo, nalazi u 3 redu i 5. koloni bi bio:

matrica[3][5]

Prethodni primer bi bio malo izmenjen

#include <stdio.h>
int main() {
    // Deklaracija dvodimenzionalne matrice
    int matrica[10][10];

    // Popunjavanje matrice i ispis elemenata
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            // Računanje vrednosti elementa
            int a = 10 * i + (j + 1);
            matrica[i][j] = a; // Stavljanje vrednosti a u memoriju matrice u i-ti red i j-tu kolonu
            // Ispis elementa sa dva mesta širine
            printf("%4d ", a);
        }

        // Novi red nakon svakog reda matrice
        printf("\n");
    }

    return 0;
}

U svakom ciklusu izračunat broj a se smešta u matricu u i-ti red i j-tu kolonu.

Ukoliko unapred znamo brojeve koje treba staviti u matricu

Npr. ocene iz nekih predmeta za više učenika mogle bi se smestiti u matricu:

int ocene[3][8] = {
    {2, 3, 2, 2, 4, 5, 5, 4},
    {2, 3, 2, 2, 4, 5, 5, 4},
    {2, 3, 2, 2, 4, 5, 5, 4}};

U uglastim zagradama je potrebno staviti dimenzije, iako su one određene sa nizovima kojim smo inicijalizovali matricu.

Dakle, 3 reda i 8 kolona. Ovde se može zaključiti da je matrica zapravo niz elemenata gde su ti elementi takođe nizovi.

Svaka kolona i red imaju svoj indeks pomoću koga se može pristupiti elementu matrice. U prethodnom primeru redovi su numerisani indeksima 0-2, a kolone indeksima 0-7.

Primer 2: Prosečna ocena svih učenika

Zadatak: Izračunati prosečnu ocenu svih učenika iz prethodno zadatih nizovaDa bi izračunali prosek moramo prethodno sabrati sve elemente matrice i podeliti sa brojem elemenata. Potrebna nam je ugnježdena for petlja:

#include <stdio.h>
int main() {
    // Deklaracija dvodimenzionalnog niza sa ocenama
    int ocene[3][8] = {
        {2, 3, 2, 2, 4, 5, 5, 4},
        {2, 5, 2, 5, 4, 5, 5, 4},
        {2, 4, 4, 2, 4, 3, 5, 4}};

    // Deklaracija promenljivih za zbir i ukupan prosek
    double ukupan_zbir = 0;
    int broj_ocena = 3 * 8; // Ukupan broj ocena
    // Petlja za prolazak kroz redove niza
    for (int i = 0; i < 3; i++) {
        // Petlja za prolazak kroz kolone niza
        for (int j = 0; j < 8; j++) {
            // Dodavanje ocene u ukupan zbir
            ukupan_zbir += ocene[i][j];

            // Ispis trenutne ocene
            printf("%d ", ocene[i][j]);
        }
        printf("\n");
    }

    // Računanje ukupnog proseka
    double ukupan_prosek = ukupan_zbir / broj_ocena;

    // Ispis ukupnog proseka
    printf("Ukupan prosek ocena: %.2f\n", ukupan_prosek);

    return 0; // Kraj programa
}

Posle pokretanja:Računanje proseka-izvršenje konzolne aplikacije

Primer 3: Izračunavanje prosečne ocene ponaosob za svakog učenika

Zadatak: Izračunati prosečnu ocenu za svakog učenika ponaosob iz prethodno zadatih nizovaDa bi izračunali prosek po svakom učeniku, onda moramo posebno sabrati svaki red ocena i podeliti sa brojem elemenata svakog unutrašnjeg niza jer red svaki ocena predstavlja ocene jednog učenika. Prosek će sada biti niz brojeva:

#include <stdio.h>
int main() {
    // Deklaracija dvodimenzionalnog niza sa ocenama
    int ocene[3][8] = {
        {2, 3, 2, 2, 4, 5, 5, 4},
        {2, 5, 2, 5, 4, 5, 5, 4},
        {2, 4, 4, 2, 4, 3, 5, 4}};

    // Promenljive za zbir ocena i prosek po učenicima
    double zbir = 0;
    double prosek[3];

    // Obrada ocena po učenicima
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 8; j++) {
            // Sabiranje ocena za učenika
            zbir += ocene[i][j];

            // Ispis trenutne ocene
            printf("%d ", ocene[i][j]);
        }

        // Računanje proseka za učenika
        prosek[i] = zbir / 8;

        // Resetovanje zbiра za sledećeg učenika
        zbir = 0;

        // Novi red za ispis
        printf("\n");
    }

    // Ispis proseka za svakog učenika
    printf("Prosek:\n");
    for (int i = 0; i < 3; i++) {
        printf("%d. %.2f\n", i + 1, prosek[i]);
    }

    return 0;
}

Posle pokretanja:

Izračunavanje prosečne ocene pojedinačno-izvršenje programa

Učitavanje matrice

U prethodnom primeru, matrica ocena je bila zadata. Da bi korisnik učitao matricu, prethodno treba da se učita broj redova i kolona.

#include <stdio.h>
int main() {
    // Deklaracija matrice i dimenzija
    int matrica[10][10];
    int m, n;

    // Unos dimenzija matrice
    printf("Unesite broj redova (m) i kolona (n): ");
    scanf("%d %d", &m, &n);

    // Provera validnosti dimenzija
    if (m > 10 || n > 10) {
        printf("Greska: Maksimalna dimenzija matrice je 10x10.\n");
        return 1;
    }

    // Unos elemenata matrice
    printf("Unesite elemente matrice (%d x %d):\n", m, n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &matrica[i][j]);
        }
    }

    // Ispis unete matrice
    printf("Uneta matrica je:\n");
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d ", matrica[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Operacije nad dvodimenzionalnim nizovima u C jeziku

Dvodimenzionalni nizovi predstavljaju matricu elemenata gde su elementi raspoređeni u redovima i kolonama. Da bismo efikasno radili sa matricama, potrebno je razumeti osnovne operacije koje uključuju prolazak kroz elemente, njihovu modifikaciju i primene u stvarnim scenarijima.

1. Prolazak kroz matricu

Najčešći način za prolazak kroz sve elemente matrice je korišćenje ugnježdenih petlji. Evo primera:

#include <stdio.h>
int main() {
    int matrica[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}};

    printf("Elementi matrice su:\n");
    for (int i = 0; i < 3; i++) { // Prolazak kroz redove
        for (int j = 0; j < 3; j++) { // Prolazak kroz kolone
            printf("%d ", matrica[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Ovaj kod ispisuje sve elemente matrice organizovane u redove i kolone.

2. Modifikacija elemenata

Da biste izmenili elemente matrice, jednostavno koristite indekse za pristup određenom elementu. Na primer:

matrica[1][1] = 10; // Menja element u drugom redu i drugoj koloni na 10

Primer: Postavite sve elemente iznad glavne dijagonale na 0.

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j > i) { // Elementi iznad glavne dijagonale
            matrica[i][j] = 0;
        }
    }
}

Praktične primene

Dvodimenzionalni nizovi se često koriste u realnim aplikacijama:

  1. Matematičke operacije: Kao što su sabiranje, oduzimanje i množenje matrica.
  2. Igračke aplikacije: Predstavljanje table za igre poput šaha ili sudokua.
  3. Manipulacija slikama: Svaka tačka slike (piksel) može biti predstavljena kao element dvodimenzionalnog niza.
  4. Sistemi preporuke: Nizovi se koriste za skladištenje podataka o preferencijama korisnika.

Na primer, množenje matrica:

#include <stdio.h>
int main() {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[3][2] = {{7, 8}, {9, 10}, {11, 12}};
    int C[2][2] = {0}; // Rezultujuća matrica
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 3; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }

    printf("Rezultujuća matrica je:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%d ", C[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Rezultat pokazuje kako se množe matrice koristeći dvodimenzionalne nizove.

Dinamičko alociranje memorije za matrice

Ponekad veličina matrice nije unapred poznata. U takvim slučajevima koristimo dinamičku alokaciju memorije. Primer:

#include <stdio.h>
#include <stdlib.h>
int main() {
    int rows = 3, cols = 3;
    int **matrica = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        matrica[i] = (int *)malloc(cols * sizeof(int));
    }

    // Inicijalizacija
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrica[i][j] = i + j;
        }
    }

    // Ispis
    printf("Dinamicki alocirana matrica:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrica[i][j]);
        }
        printf("\n");
    }

    // Oslobađanje memorije
    for (int i = 0; i < rows; i++) {
        free(matrica[i]);
    }
    free(matrica);

    return 0;
}

Primer: Skakač napada

Učitati poziciju skakača u šahu m i n i odrediti koja polja skakač napada. Ako su kolone obeležene 1-8 a redovi A-H, obeležiti šiframa polja koja skakač napada. Ostala polja obeležiti zvezdicom, osim polja gde se nalazi skakač.

Ulaz

Red i kolona koji predstavljaju poziciju skakača 1<=m<=8, 1<=n<=8

Izlaz

Šifre polja na onim poljima koji skakač napada, prazno na polju gde se nalazi skakač, zvezdice na ostalimPrimer: Skakač napadaUputstvo:

Da bi smo ispisali odgovarajući tekst na odgovarajuće polje koristićemo matricu čiji su elementi tipa string. Pošto je šahovska tabla dimenzija 8*8, a indeks u matrici počinje od nule, kreiraćemo matricu reda 9*9.

string tabla[9][9];

Treba redom proći kroz sve elemente matrice. Pošto je poslednji red u matrici prvi red u šahovskoj tabli treba formirati ugnježdenu for petlju na sledeći način:

for(int i=8; i>=1; i--)
{
for(int j=1; j<=8; j++)
{
...
}
}

Kada se naiđe na poziciju i=m, j=n, odatle treba ispisati šifre na poljima koju napada skakač. Npr. pozicija i=m+2, j=n-1 i j=n+1 itd.

Primer:

Ulaz

4

4

Izlaz

Primer Skakač napada - izvršenje

Rešenje analiza

Rešenje:

#include <stdio.h>
int main() {
    // Deklaracija matrice i dimenzija
    int m, n;
    char tabla[9][9]; // Matrica za šahovsku tablu
    // Unos pozicije skakača
    printf("Unesite poziciju skakača (red i kolona): ");
    scanf("%d %d", &m, &n);

    // Popunjavanje šahovske table
    for (int i = 8; i >= 1; i--) {
        for (int j = 1; j <= 8; j++) {
            if (i == m && j == n) {
                tabla[i][j] = ' '; // Polje skakača ostaje prazno
            } else if (
                (i == m + 2 && (j == n - 1 || j == n + 1)) ||
                (i == m - 2 && (j == n - 1 || j == n + 1)) ||
                (i == m + 1 && (j == n - 2 || j == n + 2)) ||
                (i == m - 1 && (j == n - 2 || j == n + 2))) {
                tabla[i][j] = 'S'; // Polje koje skakač napada
            } else {
                tabla[i][j] = '*'; // Ostala polja su zvezdice
            }
        }
    }

    // Ispis šahovske table
    printf("Šahovska tabla:\n");
    for (int i = 8; i >= 1; i--) {
        for (int j = 1; j <= 8; j++) {
            printf("%c ", tabla[i][j]);
        }
        printf("\n"); // Novi red nakon svakog reda table
    }

    return 0;
}

Ovaj program simulira šahovsku tablu i poziciju skakača. Skakač se u šahu kreće u obliku slova "L", tj. dva polja u jednom smeru i jedno u drugom. Program omogućava korisniku da unese poziciju skakača, a zatim računa koja polja na tabli skakač može napasti. Evo detaljnog objašnjenja svakog dela koda:

int m, n;
char tabla[9][9];

Ovaj deo koda definiše promenljive koje se koriste za skladištenje pozicije skakača na tabli (m za red i n za kolonu) i šahovsku tablu (matricu dimenzija 9x9).

printf("Unesite poziciju skakača (red i kolona): ");
scanf("%d %d", &m, &n);

Koristi se funkcija printf za ispis poruke korisniku da unese poziciju skakača, a scanf za unos rednog broja (m) i kolone (n).

for (int i = 8; i >= 1; i--) {
    for (int j = 1; j <= 8; j++) {
        if (i == m && j == n) {
            tabla[i][j] = ' ';
        } else if ((i == m + 2 && (j == n - 1 || j == n + 1)) ||
            (i == m - 2 && (j == n - 1 || j == n + 1)) ||
            (i == m + 1 && (j == n - 2 || j == n + 2)) ||
            (i == m - 1 && (j == n - 2 || j == n + 2))) {
            tabla[i][j] = 'S';
        } else {
            tabla[i][j] = '*';
        }
    }
}

U ovom delu koda kreiramo šahovsku tablu. Ako su pozicije reda i kolone jednake poziciji skakača, polje se označava praznim mestom (' '). Ako je polje napadnuto od strane skakača, označava se sa 'S'. Ostala polja se označavaju sa '*'.

printf("Šahovska tabla:\n");
for (int i = 8; i >= 1; i--) {
    for (int j = 1; j <= 8; j++) {
        printf("%c ", tabla[i][j]);
    }
    printf("\n");
}

Na kraju, koristi se dvostruka petlja za ispisivanje šahovske table. Svako polje se ispisuje, a nakon svakog reda dodaje se novi red.

return 0;

Program završava sa return 0;, označavajući uspešan završetak.

Srodne teme

Proveri znanje

Otvori kviz

Kviz: Matrice u C-u

1. Kako se deklariše matrica od 3 reda i 4 kolone?




2. U memoriji su elementi matrice smešteni:




3. Koji uslov opisuje sporednu dijagonalu n × n matrice?




4. Šta treba navesti kod parametra-matrice funkcije?