Thursday, November 19, 2015

Limbajul C. Tablouri mono si bi dimensionale. Matrici, liniarizare

Tablourile multi-dimensionale (uzual bi si tri dimensionale) sunt tablouri ale caror elemente sunt alte tablouri (mono, respectiv bi dimensionale pentru cazul uzual invocat).

tab[2][3] = {1,2,3,4,5,6}; // tab[1][1] are valoarea 5

Declaratia de sus reprezinta initializarea unei matrici bi dimensionale cu 2 linii si 3 coloane.
Putem liniariza aceasta matrice folosind un tablou mono dimensional de 6 intregi, considerand ca primele trei elemente ale sale formeaza prima linie iar ultimele, cea de-a doua linie.

Liniarizarea asigura continuitatea locatiilor de memorie in care sunt pastrate elementele, lucru care devine evident in cazul alocarii dinamice de memorie.

In cazul unui tablou multi dimensional alocat dinamic - de pilda, o matrice bi dimensionala -  compilatorul va decide pe baza unui algoritm 'propriu', in functie si de input-urile de la sistemul de operare, care vor fi adresele de inceput ale vectorilor - linie. Extrem de probabil, aceste adrese nu vor fi consecutive (consecutivitatea fiind aici corelata cu dimensiunea unui vector - line).

In exemplul urmator sunt initializate doua matrici 2 x 3, una dintre ele declarata ca atare, cealalta, liniarizata printr-un vector de 6 intregi.


De remarcat cele doua functii de afisare, care primesc ca ultim argument un tablou bi, respectiv mono dimensional. In consecinta, dereferentierea se aplica de doua ori (matricea bi dimensionala), respectiv o singura data (matricea liniarizata).

Codul si printscreen-ul:

#include <stdio.h>
void PrintMat(int m, int n, int tab[][n])
{
     int i, j;
     for(i = 0; i < m; i++)
     {
           for(j = 0; j < n; j++) printf("%d ", *(*(tab + i) + j));
           printf("\n");
     }
}

void PrintMatLin(int m, int n, int tab[])
{
     int i, j;
     for(i = 0; i < m; i++)
     {
           for(j = 0; j < n; j++) printf("%d ", *(tab + i*n + j));
           printf("\n");
     }
}

int main()
{
    int tab[2][3], tab1[6];
    int i, j;
    for(i = 0; i < 2; i++)
    for(j = 0; j < 3; j++)
    {
      printf("tab[%d][%d]: ", i, j);
      scanf("%d", &tab[i][j]);
    }
    // vectorul tab1 tratat ca matrice liniarizata
    for(i = 0; i < 2; i++)
    for(j = 0; j < 3; j++)
    {
      printf("tab1[%d][%d]: ", i, j);
      scanf("%d", tab1 + i*3 + j);
    }
    printf("\n-------------------\n");
    PrintMat(2, 3, tab);
    printf("\n-------------------\n");
    PrintMatLin(2, 3, tab1);
    return 0;
}




No comments:

Post a Comment