Ce face Tablouri bidimensionale (matrice)
O matrice în C este un tablou ale cărui elemente sunt tot tablouri. int m[3][4]; înseamnă 3 rânduri a câte 4 elemente. Accesezi un element cu m[rând][coloană], ambii indici pornind de la 0.
În memorie, rândurile stau unul după altul (ordinea pe rânduri). De aceea, la inițializare și la parametrii unei funcții poți omite doar prima dimensiune; numărul de coloane trebuie să fie cunoscut.
Din C99, o funcție poate primi dimensiunile ca parametri înaintea matricei: void afiseaza(size_t r, size_t c, int m[r][c]). Așa aceeași funcție merge pentru matrice de mărimi diferite.
Exemple
Exemplul 1: Notele a trei elevi la patru materii
Fiecare rând este un elev, fiecare coloană o materie. Bucla exterioară trece prin rânduri, cea interioară prin coloane.
#include <stdio.h>
int main(void) {
const char *elevi[] = {"Ana", "Mihai", "Ioana"};
int note[3][4] = {
{9, 8, 10, 7},
{6, 7, 8, 9},
{10, 10, 9, 10},
};
for (int i = 0; i < 3; i++) {
int suma = 0;
for (int j = 0; j < 4; j++) {
suma += note[i][j];
}
printf("%-6s media %.2f\n", elevi[i], suma / 4.0);
}
return 0;
}
Rezultat
Ana media 8.50
Mihai media 7.50
Ioana media 9.75
Exemplul 2: O funcție pentru matrice de orice mărime
Dimensiunile sunt trimise înaintea matricei, așa că parametrul m[r][c] știe câte coloane are fiecare rând.
#include <stdio.h>
void afiseaza(size_t r, size_t c, int m[r][c]) {
for (size_t i = 0; i < r; i++) {
for (size_t j = 0; j < c; j++) {
printf("%3d", m[i][j]);
}
printf("\n");
}
}
int main(void) {
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][2] = {{7, 8}, {9, 10}, {11, 12}};
afiseaza(2, 3, a);
printf("--\n");
afiseaza(3, 2, b);
return 0;
}
Rezultat
1 2 3
4 5 6
--
7 8
9 10
11 12
Exemplul 3: Rândurile sunt unul după altul în memorie
Dimensiunea totală este rânduri × coloane × dimensiunea unui element. Un rând întreg (m[0]) are 3 × 4 octeți.
#include <stdio.h>
int main(void) {
int m[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("sizeof m = %zu\n", sizeof m);
printf("sizeof m[0] = %zu\n", sizeof m[0]);
int *p = &m[0][0];
for (int k = 0; k < 6; k++) {
printf("%d ", p[k]);
}
printf("\n");
return 0;
}
Rezultat
sizeof m = 24
sizeof m[0] = 12
1 2 3 4 5 6
Greșeli frecvente
- Scrii
m[i, j]ca în alte limbaje. În C, virgula este operatorul virgulă: expresia înseamnăm[j]. Scriem[i][j]. - Declari parametrul ca
int m[][]. Compilatorul trebuie să știe numărul de coloane:int m[][4]sau varianta cu dimensiuni variabileint m[r][c]. - Confunzi o matrice cu un tablou de pointeri (
int **).int m[3][4]nu se poate trimite unei funcții care așteaptăint **: sunt tipuri diferite, cu așezare diferită în memorie.
Comenzi înrudite
Tablouri (array): Un șir de elemente de același tip, așezate unul după altul în memorie și accesate prin index, de la 0.Pointer la pointer (**): Un pointer care păstrează adresa altui pointer: util când o funcție trebuie să schimbe un pointer sau pentru tablouri de șiruri.for: Bucla cu contor: inițializare, condiție verificată înainte de fiecare pas și actualizare, toate pe un singur rând.malloc: Cere sistemului un bloc de memorie de mărimea dată, în timpul rulării, și returnează adresa lui sau NULL dacă nu reușește.