Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

08.

Vectors i matrius
UOC -2- 08. Vectors i matrius

Taula de continguts
08. Vectors i matrius ............................................................................................................................................. 3
Objectius ................................................................................................................................................................ 3
Introducció ............................................................................................................................................................. 3
1. Vectors .............................................................................................................................................................. 3
1.1. Cadenes de caràcters o strings ................................................................................................................... 5
UOC -3- 08. Vectors i matrius

08. Vectors i matrius


TAULA DE CONTINGUTS
• Objectius
• Introducció
• 1. Vectors
• 1.1. Cadenes de caràcters o strings
• 1.2. Representació en memòria
• 1.3 Inicialització
• 2. Matrius
• 3. Exemples
• 3.1. Exemple 08_06
• 3.2. Exemple 08_07
• Resum

Objectius
1. Entendre el concepte de vector i matriu.
2. Indexació en vectors i matrius.
3. Representació a memòria dels vectors i les matrius.

Introducció
Fins ara hem vist que les variables són objectes que poden contenir valors de diferents tipus, com per exemple
enters, reals o caràcters. En aquesta unitat veurem que podem definir variables que contenen diversos elements
d’un mateix tipus. Segons aquestes variables tinguin 1 o 2 dimensions, les anomenarem vectors o matrius
respectivament. També veurem com podem accedir a cadascun dels elements d’un vector o d’una matriu, i com
aquests queden emmagatzemats en memòria.

1. Vectors
Els vectors, o arrays en anglès, són estructures d’una sola dimensió, que poden emmagatzemar n valors d’un
mateix tipus. Per exemple, imagineu que volem guardar les temperatures màximes de cada dia de la setmana.
Amb el que hem vist fins ara, hauríem de definir set variables, una per a cada dia:

• Algorisme
• C
var
    t1, t2, t3, t4, t5, t6, t7: real;
end var

/* Variable declaration*/
float t1, t2, t3, t4, t5, t6, t7;

Si ho definim en forma de vector, podem crear un objecte que pugui guardar els set valors:

• Algorisme
• C

var
    t : vector[7] of real;
end var

/* Variable declaration*/
float t[7];
UOC -4- 08. Vectors i matrius

Per a accedir a l’enèsima posició d’un vector ho farem amb [n], on n és la posició a la qual volem accedir, per
exemple, t[3]. Un punt molt important que cal tenir en compte quan treballem amb vectors és quin valor té la
primera posició. En alguns llenguatges, la primera posició té un valor 0, per tant, t[0] seria la primera temperatura,
mentre que en altres llenguatges, es considera que la primera posició té valor 1 i, per tant, per a obtenir la primera
temperatura hauríem d’escriure t[1].

Quan treballem amb llenguatge algorísmic, el primer element d'un vector sempre estarà a la posició 1. Quan
treballem amb llenguatge C, la primera posició serà sempre 0.

Per tant, l’expressió per a calcular la temperatura mitjana seria:

• Algorisme
• C

    (t[1] + t[2] + t[3] + t[4] + t[5] + t[6] + t[7]) / 7.0;

    (t[0] + t[1] + t[2] + t[3] + t[4] + t[5] + t[6]) / 7.0;


Si ho posem tot junt en un algorisme que ens demani les temperatures i ens mostri la temperatura mitjana,
tindrem el següent:

[Exemple 08_01]

• Algorisme
• C

algorithm tempAverage
    var
        t: vector[7] of real;
        m: real;
    end var

    t[1] := readReal();
    t[2] := readReal();
    t[3] := readReal();
    t[4] := readReal();
    t[5] := readReal();
    t[6] := readReal();
    t[7] := readReal();

    m := (t[1] + t[2] + t[3] + t[4] + t[5] + t[6] + t[7]) / 7.0;

    writeReal(m);
end algorithm

#include <stdio.h>
int main(int argc, char** argv) {
   float t[7];
   float m;
    scanf("%f", &t[0]);
    scanf("%f", &t[1]);
    scanf("%f", &t[2]);
    scanf("%f", &t[3]);
    scanf("%f", &t[4]);
    scanf("%f", &t[5]);
    scanf("%f", &t[6]);
    m=(t[0] + t[1] + t[2] + t[3] + t[4] + t[5] + t[6]) / 7.0;
    printf("%f", m);
   return 0;
}
UOC -5- 08. Vectors i matrius

Atès que quan es carrega un programa per a la seva execució es reserva la memòria per a les seves variables
i entre elles els vectors, quan definim un vector podem utilitzar constants per a la seva dimensió, però mai
variables, ja que aquestes no tenen un valor conegut fins que ja s’està executant el programa. Per tant, podem fer:

#include <stdio.h>
#define N 3
int main(int argc, char** argv) {
   float v[N];
}

Però no podem fer:

#include <stdio.h>
int main(int argc, char** argv) {
   int m;
   m := 3;
   float v[m];
}

Quan la longitud d’un vector és una dada del problema, és una bona pràctica definir-la com una constant, ja
que ens permet modificar aquesta dada ràpidament. Per exemple, si en el cas de les temperatures setmanals les
volguéssim canviar perquè fossin anuals, caldria canviar el nombre de posicions 7 per 365, i en el càlcul de la
mitjana també caldria dividir per 365 en comptes de 7. Si ho tinguéssim definit a partir d’una constant, solament
caldria canviar la constant.

1.1. Cadenes de caràcters o strings


Un tipus molt utilitzat de vector són les cadenes de caràcters, sovint conegudes pel seu nom en anglès strings.
En C, per a definir una cadena de caràcters ho farem com un vector normal, però cal tenir en compte que les
cadenes de caràcters, per a poder ser interpretades com a tals, han de finalitzar sempre amb el caràcter (‘\0’), que
té valor ASCII 0. Per tant, si volem guardar una cadena de caràcters caldrà reservar memòria per a una posició
addicional. 

En llenguatge algorísmic generalment no es declara com a vector sinó com a cadena de caràcters. A
continuació es mostra un exemple:

[Exemple 08_02]

• Algorisme
• C

algorithm sayHello
    var
        name: string;
    end var

    writeString("What's your name?");


    name := readString();

    writeString("Hello");
    writeString(name);

end algorithm

#include <stdio.h>
#define MAX_NAME_LEN 25
int main(int argc, char** argv) {
   char name[MAX_NAME_LEN];
    printf("What's your name?\n");
    scanf("%s", name);
    printf("Hello %s\n", name);
   return 0;
UOC -6- 08. Vectors i matrius

Fixeu-vos que en el cas de les cadenes de caràcters, quan utilitzem la instrucció en C scanf no posem el símbol
& davant.

Amb els strings podem utilitzar els mateixos operadors externs que amb els caracters =, ≠, <, >, ≤, ≥  per
comparar-los. La comparació es fa seguint l'ordre alfabètic començant pel primer caracter.

1.2. Representació en memòria


Totes les posicions d’un vector es guarden en memòria consecutivament i, per tant, un vector de n posicions
ocuparà n vegades el que ocupa el seu tipus bàsic. Per exemple, si tenim un vector d’enters a, i un enter ocupa
4 bytes en memòria de manera que ocupa fins a la posició X, el vector de 4 enters ocuparà 4x4 = 16 bytes en
memòria:

… X-1 X-2 X-3 X-4 X-5 X-6 X-7 X-8 X-9 X-10 X-11 X-12 X-13 X-14 X-15 X-16 …
… 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 …

a[3] a[2] a[1] a[0]

a
UOC -7- 08. Vectors i matrius

La representació gràfica de com queda en memòria una variable és una eina molt útil per a fer el seguiment
del programa. A aquest efecte, podem posar en ordre invers les posicions, suposar que la posició inicial és 0 i
agrupar els bytes que contenen un valor del vector. Per exemple, si el vector conté els valors {1, 4, -1, 1023}, el
podem representar com:

… 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 …
… 1 4 -1 1023 …

a[0] a[1] a[2] a[3]

1.3 Inicialització
Com a bona pràctica, primer definirem el vector, especificant la seva mida màxima, i posteriorment l'inicialitzarem.
Per exemple:

[Exemple 08_03]

• Algorisme
• C

algorithm vectors
UOC -8- 08. Vectors i matrius

    var
        v1 : vector[3] of integer;
        v2 : vector[4] of integer;
    end var

     v1[1] := 3;
     v1[2] := 5;
     v1[3] := -1;

     v2[1] := 3;
     v2[2] := 5;
     v2[3] := -1;

end algorithm

#include <stdio.h>
int main(int argc, char** argv) {
   /* Variable definition*/
   int v1[3];
   int v2[4];
    v1[0] = 3;
    v1[1] = 5;
    v1[2] = -1;
    v2[0] = 3;
    v2[1] = 5;
    v2[2] = -1;
   return 0;
}

En el cas de v2, és un vector de 4 posicions del que solament inicialitzem les 3 primeres.

En el cas de les cadenes de caràcters, podem utilitzar les cometes dobles ("), o tractar-ho igual que un vector
normal i assignar caràcter a caràcter. A continuació tenim un exemple on, per a cada string, es mostra el seu
contingut, la mida en bytes i la quantitat de caràcters (es comptabilitzen fins a trobar el símbol de final de cadena
'\0').

[Exemple 08_04]

#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
   char a[4];
   char b[5];
   char c[4];
   char d[5];
    a[0] = 'a';
    a[1] = 'b';
    a[2] = 'c';
    a[3] = '\0';
    b[0] = 'a';
    b[1] = 'b';
    b[2] = 'c';
    b[3] = '\0';
    strcpy(c, "abc");
    strcpy(d, "abc");
    printf("a - %s --> (%d) bytes, (%d) chars\n", a, sizeof(a), strlen(a));
    printf("b - %s --> (%d) bytes, (%d) chars\n", b, sizeof(b), strlen(b));
    printf("c - %s --> (%d) bytes, (%d) chars\n", c, sizeof(c), strlen(c));
    printf("d - %s --> (%d) bytes, (%d) chars\n", d, sizeof(d), strlen(d));
   return 0;
}
UOC -9- 08. Vectors i matrius

2. Matrius
Les matrius són vectors de dues dimensions. Per exemple, per a definir la matriu:

##= (14 2
5
3
6 )

Ho podem fer de la manera següent:

• Algorisme
• C

algorithm matrix
    var
        m : vector[2][3] of integer;
    end var
    m[1][1] := 1;
    m[1][2] := 2;
    m[1][3] := 3;
    m[2][1] := 4;
    m[2][2] := 5;
    m[2][3] := 6;
end algorithm

#include <stdio.h>
int main(int argc, char** argv) {
   /* Variable definition*/
   int m[2][3];
    m[0][0] = 1;
    m[0][1] = 2;
    m[0][2] = 3;
    m[1][0] = 4;
    m[1][1] = 5;
    m[1][2] = 6;
   return 0;
}

Tingueu en compte que primer es declara el nombre de files i després el de columnes.

Igual que en el cas dels vectors unidimensionals, amb els de n-dimensions l'índex de les posicions comença per 1
amb llenguatge algorísmic, i per 0 amb llenguatge C.

A continuació es mostra un exemple en el qual es calcula el valor mitjana de tots els valors de la matriu
anterior.

[Exemple 08_05]

• Algorisme
• C

algorithm matAverage
UOC - 10 - 08. Vectors i matrius

    var
        m : vector[2][3] of integer;
        r : real;
    end var

    m[1][1] := 1;
    m[1][2] := 2;
    m[1][3] := 3;
    m[2][1] := 4;
    m[2][2] := 5;
    m[2][3] := 6;

    r := integerToReal(m[1][1] + m[1][2] + m[1][3] + m[2][1] + m[2][2] + m[2][3]);


    r := r/6.0;

    writeReal(r);
end algorithm
#include <stdio.h>
int main(int argc, char** argv) {
   /* Variable definition*/
   int m[2][3];
   float r;
    m[0][0] = 1;
    m[0][1] = 2;
    m[0][2] = 3;
    m[1][0] = 4;
    m[1][1] = 5;
    m[1][2] = 6;
    r = (m[0][0] + m[0][1] + m[0][2] + m[1][0] + m[1][1] + m[1][2]) / 6.0;
    printf("%f\n", r);
   return 0;
}

Quan es guarda en memòria, es fa per files. Per tant, una matriu com l’anterior en memòria és equivalent a un
vector de 2x3 = 6 posicions i per tant de 6x4 = 24 bytes.
UOC - 11 - 08. Vectors i matrius

… 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 …
… 1 2 3 4 5 6 …

m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2]

3. Exemples
3.1. Exemple 08_06
Definir un algorisme que calculi el producte escalar de dos vectors en un espai de dues dimensions (2D).

• Algorisme
• C

algorithm dotProduct
    var
        a : vector[2] of integer;
        b : vector[2] of integer;
        c : integer;
    end var
UOC - 12 - 08. Vectors i matrius

    a[1] := readInteger();
    a[2] := readInteger();
    b[1] := readInteger();
    b[2] := readInteger();

    c := a[1] * b[1] + a[2] * b[2];

    writeInteger(c);
end algorithm

#include <stdio.h>
int main(int argc, char** argv) {
   /* Variable definition*/
   int a[2], b[2];
   int c;
    scanf("%d", &a[0]);
    scanf("%d", &a[1]);
    scanf("%d", &b[0]);
    scanf("%d", &b[1]);
    c = a[0] * b[0] + a[1] * b[1];
    printf("(%d,%d) * (%d,%d) = %d\n", a[0], a[1], b[0], b[1], c);
   return 0;
}

3.2. Exemple 08_07


Definir un algorisme que calculi el producte entre la matriu identitat de 3x3 i un valor enter introduït per teclat.

• Algorisme
• C

algorithm dotProduct
    var
        id : vector[3][3] of integer;
        s : integer;
        r : vector[3][3] of integer;
    end var

    id[1][1] := 1;
    id[1][2] := 0;
    id[1][3] := 0;
    id[2][1] := 0;
    id[2][2] := 1;
    id[2][3] := 0;
    id[3][1] := 0;
    id[3][2] := 0;
    id[3][3] := 1;

    s := readInteger();
    r[1][1] := id[1][1] * s;
    r[1][2] := id[1][2] * s;
    r[1][3] := id[1][3] * s;
    r[2][1] := id[2][1] * s;
    r[2][2] := id[2][2] * s;
    r[2][3] := id[2][3] * s;
    r[3][1] := id[3][1] * s;
    r[3][2] := id[3][2] * s;
    r[3][3] := id[3][3] * s;

end algorithm
UOC - 13 - 08. Vectors i matrius

#include <stdio.h>
int main(int argc, char** argv) {
   /* Variable definition*/
   int id[3][3];
   int s;
   int r[3][3];
    id[0][0] = 1;
    id[0][1] = 0;
    id[0][2] = 0;
    id[1][0] = 0;
    id[1][1] = 1;
    id[1][2] = 0;
    id[2][0] = 0;
    id[2][1] = 0;
    id[2][2] = 1;
    scanf("%d", &s);
    r[0][0] = id[0][0] * s;
    r[0][1] = id[0][1] * s;
    r[0][2] = id[0][2] * s;
    r[1][0] = id[1][0] * s;
    r[1][1] = id[1][1] * s;
    r[1][2] = id[1][2] * s;
    r[2][0] = id[2][0] * s;
    r[2][1] = id[2][1] * s;
    r[2][2] = id[2][2] * s;
   return 0;
}

Resum
En aquesta unitat hem vist com definir i inicialitzar vectors i matrius, tant en llenguatge algorísmic com en els
llenguatges de programació. També hem vist com accedir als valors d’un vector i matriu tant per a utilitzar-los com
per a assignar nous valors. A més hem vist que les cadenes de caràcter són un vector amb algunes propietats
que cal tenir en compte quan programem en llenguatge C.

You might also like