You are on page 1of 5

Matrius i vectors dinàmics

Una matriu és semblant a un edifici, a on hi viuen moltes famílies en una mateixa


planta, per exemple a la 5 planta viuen 4 persones una en cada pis. Un edifici té un
porter automàtic. Si piquem a la 5ena fila, 3a columna cridem al senyor que viu al pis 5e
3ª. Així doncs, la fila i la columna em permeten accedir a l’element habitant(5,3). Les
matrius són útils per tal de agrupar dades com en el següent exemple.

Imaginem que tenim el següent problema. Un observador meteorològic, ens demana que
li fem un programa per guardar les dades de temperatura que té en una taula com
aquesta

A les 7 del mati A les 12 del migdia A les 19 hores


Dilluns 7 12 19
Dimarts 10 15 12
Dimecres 15 17 15
Dijous 7 6 8
Divendres 12 12 12
Dissabte 7 16 1
Diumenge 12 19 12

Aquestes dades, si les volem representar en C#, ens farà falta 7 vectors, de 3
components cadascun, o bé una matriu de 7 files, ( una per cada dia de la setmana) i 3
columnes una per cada hora que s’ha mesurat la temperatura.
Les matrius ens permeten guardar dades que com aquestes estan en forma d’una taula
amb dues entrades, una per les hores de mesura, i una altre pels dies. En general ens fan
falta dos indexes, per recórrer una matriu, un per les files i un altre per les columnes.

Per declarar una matriu farem

float[,] temperatures = new float[7, 3];

Aquí hem declarat la matriu temperatures, que té 7 files ( de 0 a 6) i 3 columnes (de 0


fins 2)
Es molt interessant fer el següent

const int NF = 7;
const int NC = 3;
float[,] temperatures = new float[NF, NC];

Així tot depèn de les constants NF,NC, i no cal anar posant les dimensions
explícitament al llarg del programa. Si en el futur cal canviar les dimensions, ( perquè
prenem més mesures de la temperatura, només caldrà modificar aquestes constants i el
programa funcionarà correctament.

També es pot inicialitzar la matriu al moment de crear-la


float[,] temperatures = new float[, ] {{2.3f,4.5f},{5.2f,3.2f}};

Això ens crea una matriu mat de dos files i dos columnes,

2.3 4.5
5.2 3.2

Fixeu-vos que no posem cap numero en la sentencia new float[,] ja que el C# amb
la informació que donem, en te prou per deduir que la matriu té dues files ( 0, 1) i dues
columnes ( 0, 1) A més fixeu-vos que en les comes, a dintre del {} hi ha una per
separar el 2.3 del 4.5 i el 5.2 del 3.2, a més a més hi ha una coma per separar la fila
{2.3f,4.5f} de la fila {5.2f,3.2f}.Una vegada tenim declarada la matriu
temperatures, la podem inicialitzar com sempre amb dos bucles for
for (f = 0; f <= temperatures.GetUpperBound(0); f++)
{
for (c = 0; c <= temperatures.GetUpperBound(1); c++)
{
temperatures[f, c] = float.Parse(Console.ReadLine());
}
}

I per imprimir la matriu, només cal fer el mateix, amb dos bucles for, mostrar els
elements de la matriu

for (f = 0; f <= temperatures.GetUpperBound(0); f++)


{
for (c = 0; c <= temperatures.GetUpperBound(1); c++)
{
Console.Write("{0,5:f2}", temperatures[f, c]);
}
Console.WriteLine();
}

Aquí fem servir GetUpperBound(index) per trobar el valor màxim de la fila ( índex 0) o
de les columnes ( índex 1). Fixeu-vos que hem de fer que les files vagin de 0 fins al
valor retornat per temperatures.GetUpperBound(0) per això posem <=, igual passa amb
les columnes c.
Per accedir a un element de la matriu, hem de posar la fila i la columna corresponent,
així temperatures[f,c] dintre del for, va recorrent tots els elements de la matriu.

Les matrius a més són objectes a dintre de C# i podem cridar mètodes per saber coses
sobre les matrius per exemple el mètode rank, ens dona el número de dimensions, 2
vol dir que hi té dos dimensions, fila i columna.

Console.WriteLine(" la matriu te :{0,3:d} dimensions",


temperatures.Rank)

Ens dirà que té dos dimensions, si ara volem saber quin és l’ últim índex de les files
pensem que el C# identifica les matrius primer per la fila i després per la columna, així
la primera dimensió serà 0 ( C# comença sempre a contar des de 0) i la segona dimensió
serà 1.
Console.WriteLine(" ultim index de les files :{0,3:d} i ultim index
de les columnes {1,3:d} columnes ", temperatures.GetUpperBound(0),
temperatures.GetUpperBound(1))

També tenim els mètodes getLowerBound(índex) per trobar el valor inicial de


l’índex que de la matriu, el nostre cas sempre surt 0 ja que tots els índex, ( files i
columnes) comencen per 0, això pot no ser sempre cert.

Un altre mètode útil, és GetValue, a aquest mètode li passem la fila i columna que
volem veure i ens treu l’element que viu allà. Es semblant a picar al porter automàtic

Console.writeline( “ el dilluns a les 12 del migdia feia


{0,5:f2} “ , temperatures.GetValue(0,1))

Aquí hem passat a GetValue els indexes de la fila , columna que volem 0 per dilluns,
1 per la columna corresponent a les temperatures de les 12 del migdia.

Per imprimir les matrius d’una manera que es vegi els valors de la fila i la columna
podem fer servir un format tal com us havia explicat fa uns dies, podem fer el següent

Primer declarem una cadena que ens servirà per construir la sortida de la impressió
Després fem servir

Cadena=string.format(“temperatura( {0,2 :d},
{1,2 :d})={2,5 :f2} “,f,c,temperatura[f,c])

Aquí veiem que cada una de les variables que volem treure té el seu format, per
exemple les files f tenen {0,2:d} mentre que temperatures com és un single farem servir
el format f {2,5:f2} que diu que tindrà 5 espais i format float amb 2 decimals

Una vegada tenim aquesta cadena amb la informació que volem donar, ja podem
imprimir-la amb

Console.writeline( cadena)

Es important notar que la cadena que construïm esta feta de parts que nosaltres posem
per exemple temperatura i parts que el C# substitueix pels valors de les variables.
Aquestes parts han d’anar entre claudàtors {} i amb el següent format

{ índex, alineament:format <c|f|g|e|p|d|x>numero de decimals}

c serveix per quantitats monetàries diners


f serveix per singles ( números amb decimals)
g format genèric per números amb decimals
e format científic amb 10e-2 per exemple
p per mostrar percentatges
d per mostrar integres
x per mostrar nombres hexadecimals
Com construïm una cadena, aquesta cadena pot ser també assignada a una caixa de text,
amb la propietat text de la caixa de text

TxtResultat.text= cadena

A on tindrem el resultat amb el format que volem.

Fins aquí hem parlat de matrius, amb dos dimensions, files i columnes, però ningú ens
impedeix fer coses amb 3 dimensions, o 4 ... o 10, si ens va bé pel problema en qüestió.
La mecànica és la mateixa

const int NX = 3;
int[, ,] mat = new int[NX, NX, NX];
int f,c, p;
for (f = 0; f <= mat.GetUpperBound(0); f++)
{
for (c = 0; c <= mat.GetUpperBound(1); c++)
{
for (p = 0; p <= mat.GetUpperBound(2); p++)
{
mat[f, c, p] = Int32.Parse(Console.ReadLine());
}

}
}

Depuració de programes

De vegades, tot i que hem pensat bé el programa, hem fet el pseudocodi, el programa
compila bé però el programa no funciona com esperàvem, hem fet un error en algun lloc
sigui lògic ( ens hem equivocat en el pseudocodi, alguna condició no es compleix, algun
procés no fa el que ha de fer). Per això tenim una eina molt útil, el depurador, que ens
permet seguir la evolució d’un programa, i veure a on ens hem equivocat, comprovar el
valor de les variables, veure si una instrucció s’executa i com canvia els valors de les
variables.

Una idea relacionada amb això, és la de breakpoint o punt de ruptura del flux
d’execució del programa, és una instrucció a on posem un breakpoint per veure pas a
pas com s’està executant el codi. Fem un petit exemple per veure com funciona.

Imaginem que tenim un programa com aquest


class Program
{
static void Main(string[] args)
{
Random r = new Random();
int secret=r.Next(1,7);
int aposta=0;
bool continuar = true;
int nvegades = 0;
do
{
Console.Write("posa la teva aposta :");
aposta = Int32.Parse(Console.ReadLine());
if (aposta != secret)
{
continuar = true;
}
else
{
continuar = false;
}

nvegades++;
} while (continuar == true);
Console.WriteLine(" el numero secret era :{0,3:d}", secret);
Console.WriteLine("has necessitat : {0,3:d} vegades per encertar ",
nvegades);
Console.ReadLine();
}

Aquest programa fa servir nombres aleatoris i per tant, si no mirem a dintre el que està
passant és difícil saber si funciona correctament o no. Anem a depurar-lo. Primera cosa,
triarem un breakpoint. Per fer-ho, cal triar una línea del codi, i apretar F9, us apareix la
línea en vermell amb un petit punt vermell al costat. Això indica que la execució del
programa es pararà aquí. Al fer F5 el programa es posa en marxa, fins arribar a la línea
marcada, just abans d’executar-la. Si fem F8 executarà la línea, per exemple si posem
un breakpoint a on llegim la aposta, al fer F8 el programa demanarà el valor de aposta
pel teclat. A partir d’aquí podem mirar el valor de les variables, posant el ratolí a sobre,
podem fer execucions pas a pas amb F8, o bé la icona del menú, si fent F8 ens fiquem
molt a dintre del codi, podem sortir fent Control- Shift-F8 (control- majúscules F8). Si
volem passar per sobre d’una funció que sabem que fa bé la feina fem un step over, és a
dir, saltem per sobre amb Majúscules-F8.

El depurador NO substitueix un bon disseny, pseudocodi, etc, és una eina per corregir
petits errors, o per fer comprovacions.

You might also like