Le Matrici (by ennius) - Atto unico. - dal 04/09/04 pagina vista: volte

Parlare di matrici per me rappresenta un grosso exploit, vista la mia dichiarata (più volte sui siti) mancanza di comprendere le matrici. A differenza di Mike, che sguazza tranquillamente e piacevolmente nel mare Matrix, ho sempre avuto grosse difficoltà nel comprendere le matrici, e quindi utilizzarle.

Vediamo intanto come la guida in linea definisce una matrice:

"Gruppo di elementi indicizzati in sequenza che possiedono lo stesso tipo di dati intrinseco. A ciascun elemento di una matrice viene assegnato un numero di indice univoco che lo identifica. Le modifiche apportate a un elemento di una matrice non influenzano gli altri elementi."

Francamente io non avrei comunque capito granchè da questa spiegazione, se non che una matrice è un insieme di dati (elementi) che vengono identificati attraverso un numero indice assegnato ad ogni elemento. Ma fino a qui non ci sono grossi problemi, solo non so come devo fare per impostare dei dati in matrice, e come posso utilizzarli, insomma mi sento molto "gnocco".

Debbo comunque subito precisare che per lavorare con le matrici è necessario conoscere come funzionano i cicli For..Next, cicli necessari a scorrere un insieme di dati, (anche di una matrice, appunto), sia per memorizzarli per poterli poi utilizzare, sia per poterli eventualmente modificare prima di utilizzarli.

Abituato a ragionare coi cicli For Next per leggere, modificare, cancellare, copiare, o comunque intervenire sui dati contenuti in una tabella (o database, è la stessa cosa, in Excel), distribuita su celle , dove ogni dato letto dal ciclo, sostituisce il dato precedentemente letto (una volta usato, scritto in una cella), non immaginavo, non sapevo, non intuivo, e non ho mai capito le spiegazioni (forse date per scontate dagli autori dei molti libri che ho letto sull'argomento "matrici") che ora invece mi accingo a descrivere. Devo sicuramente ringraziare Mike, che in un altro disperato quanto arduo tentativo di spiegarmi le matrici, ha finalmente acceso una lampadina che stava da qualche parte del mio modesto (e limitato) cervello.

Non voglio parlare quindi di matrici in forma tecnica (esistono articoli specifici di Mike che spiegano a sufficienza l'argomento matrici, (vedi i suoi articoli
Le Matrici" e " Uso pratico delle matrici" sul suo sito,) ma solo spiegare come un neofita dell'argomento matrici (io) è riuscito perlomeno e finalmente a capirci qualcosa (poco in verità). Può darsi che riesca ad aiutare quanti come me (i duri di comprendonio), vagano nelle tenebre nonostante gli articoli di Mike.

Vediamo quindi la procedura che mi ha inviato Mike come alternativa al problema citato nell'articolo "Copia per lunghezza testo", in questa sezione), e che serve ad ordinare dei fogli di una cartella, usando appunto una Matrice:

Sub FogliInOrdine()
' punto primo raccolgo i nomi dei fogli in una matrice
Dim iFogli() As Variant, CL As Object
Dim A, B, C, N
N = Application.Worksheets.Count
ReDim iFogli(1 To N)
A = 1
For Each CL In Worksheets
iFogli(A) = CL.Name
A = A + 1
Next

' metto in ordine la matrice
For A = LBound(iFogli) To UBound(iFogli) - 1
For B = A + 1 To UBound(iFogli)
If iFogli(A) < iFogli(B) Then
C = iFogli(A)
iFogli(A) = iFogli(B)
iFogli(B) = C
End If
Next
Next

' sposto i fogli prelevandone i nomi dalla matrice
' davanti al primo foglio

For A = LBound(iFogli) To UBound(iFogli)
If iFogli(A) <> "" Then
Worksheets(iFogli(A)).Move before:=Worksheets(1)
End If
Next
End Sub

Sono stati i primi due commenti in verde che mi hanno "svegliato" :

  • punto primo raccolgo i nomi dei fogli in una matrice

  • metto in ordine la matrice

infatti queste semplici frasi mi hanno fatto capire che i nomi dei fogli vengono letti e MANTENUTI  TUTTI IN MEMORIA, (raccolgo i nomi) e non, come ho sempre pensato, che ogni nome letto dal ciclo For sostituisse in memoria quello letto precedente, quindi una MATRICE ora me la posso figurare come una tabella di Dati, CHE ANZICHE' ESSERE SCRITTI su un foglio, sono TUTTI SCRITTI nella MEMORIA (RAM).

Una volta accesa la mia "lampadina" personale, non è stato difficile capire, attraverso la frase (metto in ordine..) che i dati tenuti in memoria, si possono modificare (ordinarli alfabeticamente, copiarli in un'altra posizione, filtrarli, ecc.) come siamo (e sono) abituato a fare con i dati scritti sui fogli di lavoro.

Chi legge potrà stupirsi di questo articolo, ma io e le matrici fino ad ora non ci eravamo mai capiti, fino a che Mike, con due piccole frasi, mi ha fatto capire ciò che libri e tanti articoli letti non erano riusciti nell'intento. Vorrei aggiungere che spesso due semplici parole riescono dove corposi e ponderosi capitoli falliscono. Le strade che il nostro cervello usa per apprendere sono decisamente strane e incomprensibili, e non sempre sono visibili.

Parlare di matrici dovrebbe necessariamente obbligarmi a parlare del loro dimensionamento, di matrici a una dimensione, bidimensionali, multidimensionali, ecc. ma questi argomenti li trovate tutti, e spiegati bene, nei due articoli di Mike citati ad inizio pagina. Unica cosa che è necessario qui ricordare, è che gli elementi che compongono una matrice vengono identificati da un numero indice che iniziando da zero ( 0 ) si incrementerà di tanti valori quanto saranno gli elementi che compongono la matrice. Cioè se una matrice è a 10 elementi i numeri indice partono da 0 e terminano a 9.

Proseguo invece tentando di spiegare come sono riuscito a mettere in pratica quanto ho appreso. Seguendo l'esempio che Mike mi ha inviato, provando e riprovando, non a mettere in ordine i fogli, ma a memorizzare, mettere in ordine, estrarre dati contenuti in una colonna di un foglio di lavoro: mi sono quindi preparato una tabellina con un pò di nominativi, occupando le celle della colonna A, simulando quindi un database ad una sola colonna (avremo quindi una matrice monodimensionale = una sola colonna). Vediamo quindi la procedura, spiegando passo passo cosa avviene:

Matrice ad una dimensione.

Sub MiaMatrice()


Dim iNomi() As Variant, CL As Object
'dichiarazioni della matrice iNomi() e di CL come Object (le celle scorse 'dal ciclo For Each)
Dim A, F, C, N
'dichiarazioni di variabili di tipo Variant
N = ActiveSheet.UsedRange.Rows.Count
'con N otteniamo il numero di quante righe compongono l'elenco, e N 'rappresenterà il limite estremo della matrice, cioè il numero massimo degli elementi che comporranno la matrice
ReDim iNomi(1 To N)
'con ReDim dimensioniamo la matrice, indichiamo cioè il numero di elementi che 'comporranno la matrice, e si indica il limite inferiore (1) To limite superiore (N). Quando uno dei valori che 'delimitano la matrice è rappresentato da una variabile (N) (non sappiamo infatti quante saranno le righe occupate 'nell'elenco, quindi le contiamo appunto assegnando ad una variabile N questo numero) si usa ReDim, altrimenti, 'sapendo a priori il numero esatto di righe dell'elenco, per dimensionare la matrice sarebbe sufficiente la sintassi 'Dim iNomi(1 To 15) (senza Redim)
A = 1
'usiamo la variabile A come un contatore e lo inizializziamo a 1
For Each CL In Range(Cells(1, 1), Cells(N, 1))
'ora si inizia un ciclo che scorra ogni cella a partire dalla cella 1^ 'riga '(1^ colonna) fino alla cella riga N (l'ultima occupata da dati)
iNomi(A) = CL.Value
' e si assegna al numero indice A della matrice (iNomi) il valore contenuto nella cella ora 'letta
A = A + 1
' si incrementa il contatore di una unità, ed è questo che consente di scorrere i numeri indice della 'matrice in contemporanea all'avanzamento alla cella successiva ottenuta con Next
Next

......segue

bene, dopo aver lanciato queste istruzioni, noi avremo caricato la nostra matrice con in nomi che sono sul foglio; possiamo immaginare il contenuto di una matrice come un'elenco di dati in una casella di riepilogo, ma senza la casella, tanto per intenderci, una cosa del genere:

 la colonna A del foglio, con i nomi :  la matrice contiene ora (in memoria) i dati :

numero indice(0)
numero indice(1)
numero indice(2)
numero indice(3)
numero indice(4)
numero indice(5)
numero indice(6)
numero indice(7)
numero indice(8)
numero indice(9)
numero indice(10)
numero indice(11)
numero indice(12)
numero indice(13)


Ora i dati sono lì, in memoria, e li possiamo usare; simuliamo quindi di volerli ordinare alfabeticamente prima di copiarli in una altra zona del foglio o di un'altro foglio. Usiamo ancora la routine esempio di Mike, che provvede al riordino dei dati in matrice. La sua "pensata" è stata per me un aiuto fondamentale: usa un doppio ciclo For Next nel quale fa leggere un dato attraverso il suo numero indice, e lo compara col successivo; se il dato letto è maggiore del successivo, allora li sostituisce mettendo il minore sopra il maggiore. Poichè i cicli scorrono volta volta tutti i dati, alla fine dei cicli si ottiene un'ordinamento dal minore al maggiore. Mike dice che esistono anche altri sistemi per l'ordinamento di matrici, ma non essendo io ancora in grado di capirli, utilizzo la sua procedura che funziona egregiamente; vediamo questa parte di istruzioni:

' metto in ordine la matrice
'inizia il doppio ciclo: il contatore A sarà il valore che indicherà ad ogni ciclo, il numero indice della matrice che 'inizia dal valore minimo di indice (LBound) e termina al valore massimo di indice (UBound), meno uno; infatti il 'ciclo A dovrà terminare al penultimo dato in matrice. Chiaramente per scorrere i cicli devono essere usati dei 'numeri (i numeri indice), ma sarà il dato corrispondente ad un numero indice ad essere valutato, e non il numero 'indice.
For A = LBound(iNomi) To UBound(iNomi) - 1

'con F invece si ottiene il numero indice (e quindi il dato) immediatamente successivo al dato A  (A+1), e quindi il 'secondo ciclo scorrerà tutti i dati partendo dal successivo di A e fino alla fine.
For F = A + 1 To UBound(iNomi)

'ora si verifica se il dato rappresentato da A (della variabile iNomi) è maggiore di F, se così avviene, allora si 'scambiano di posto usando una variabile di appoggio, di scambio, la C
If iNomi(A) > iNomi(F) Then
'per ordinare A-Z
 
'If iNomi(A) < iNomi(B) Then 'se invece si volesse ordinare ordinare Z-A
C = iNomi(A)
iNomi(A) = iNomi(F)
iNomi(F) = C
End If
Next
Next

.........segue

dopo questo passaggio, la nostra matrice sarà ordinata (sempre in memoria) alfabeticamente, così:

Ora possiamo decidere cosa fare con questi dati; ho preparato tre varianti, ognuna delle quali rappresenta l'ultimo gruppo di istruzioni che chiuderanno la Sub MiaMatrice(); vogliono essere solo degli esempi delle tante soluzioni che potremmo scegliere avendo a disposizione quei dati:

  • 1) - copiare i dati ora ordinati in altra zona del foglio.

  • 2) - riempire una ListBox con i dati ora ordinati

  • 3) - estrarre solo una parte dei nomi indicando le iniziali (prese tramite due InputBox) dei nomi da comprendere. (ma anche copiare questa selezione su celle di un foglio).

1^ soluzione:

  • ' copio i nomi prelevandoli dalla matrice e scrivendoli nella colonna B
    rig = 1  'indico con la variabile "rig" da quale riga iniziare a copiare, poi inizio un ciclo che scorra tutta la matrice dal 'numero indice inferiore a quello superiore, usando la variabile A come contatore del ciclo
    For A = LBound(iNomi) To UBound(iNomi)
    Cells(rig, 2) = iNomi(A)
    'quindi rendo la cella riga "rig", colonna 2 uguale al dato corrispondente all'indice A della 'matrice iNomi, che si incrementerà di una unità ad ogni ciclo tramite Next
    rig = rig + 1
    'incremento il numero di riga di una unità
    Next
    End Sub

2^ soluzione:

  • 'inserisco i nomi in una ListBox posta sul foglio di lavoro; poichè uso il metodo AddItem per caricare la ListBox, è meglio prevedere di "pulire" prima la ListBox nel caso che si sia già lanciata la macro (altrimenti i dati si aggiungerebbero a quelli precedenti) :

  • M = Sheets(1).ListBox1.ListCount - 1 'con M ottengo il numero di dati presenti nella ListBox
    If M >= 0 Then 
    'se esistono dati (M maggiore di 0)
    For Z = M To 0 Step -1
     'inizio un ciclo che parte dall'ultimo dato presente, scorrendo verso il primo (Step -1)
    Sheets(1).ListBox1.RemoveItem Z
     'e rimuovo il dato con RemoveItem
    Next
    End If
    For A = LBound(iNomi) To UBound(iNomi)
    'inizio il ciclo che tramite il contatore A
    Sheets(1).ListBox1.AddItem iNomi(A)
     'aggiunge alla ListBox il dato A contenuto in matrice
    End If
    Next

3^ soluzione:

  • 'questa soluzione risulta indicata quando si voglia "estrarre" filtrandoli, solo nomi (o valori) corrispondenti ad un preciso criterio; in questo esempio ho predisposto come criterio di selezione la possibilità di definire l'intervallo delle iniziali dei nomi che ci interessano; è chiaro che potremo avere tutto l'elenco contenuto in matrice indicando da "a" a "zz", oppure tutti i nomi compresi tra "h" e "pz" ad esempio. Anche in questo caso potremo ottenere il risultato della filtrazione copiando i nomi su celle di un foglio, oppure caricare una ListBox (o ComboBox).

  • iniz = InputBox("SCRIVI L'iniziale del primo nome") 'usiamo due inputbox per reperire le due lettere dell'intervallo
    fine = InputBox("SCRIVI L'iniziale dell'ultimo nome")
    rig = 1
    For A = LBound(iNomi) To UBound(iNomi)
    If iNomi(A) >= iniz & "*" And iNomi(A) <= fine & "z" & "*" Then
    'ora si comparano le iniziali per estrarre solo i 'nomi che rientreranno nei criteri previsti
    Cells(rig, 2) = iNomi(A)
    'e scriviamo il nome nella cella riga "rig" colonna B
    rig = rig + 1  
    'incrementiamo il numero di riga
    End If
    Next
    End Sub

se invece che scriverli nelle celle, questi nomi filtrati, li vogliamo inserire in una ListBox, il procedimento è lo stesso visto più sopra, ma con l'aggiunta delle due inputbox:

  • M = Sheets(1).ListBox1.ListCount - 1
    If M >= 1 Then
    For Z = M To 0 Step -1
    Sheets(1).ListBox1.RemoveItem Z
    Next
    End If
    iniz = InputBox("SCRIVI L'iniziale del primo nome")
    fine = InputBox("SCRIVI L'iniziale dell'ultimo nome")
    For A = LBound(iNomi) To UBound(iNomi)
    If iNomi(A) >= iniz & "*" And iNomi(A) <= fine & "z" & "*" Then
    Sheets(1).ListBox1.AddItem iNomi(A)
    End If
    Next
    End Sub

Come avete visto, le procedure per la gestione dei dati sono simili a tante altre viste in procedure senza matrici, presenti su questi siti. Lo scoglio (per me) delle "Matrici" ora sembra raggiunto e quasi superato, ma non è così, c'è ancora molta strada da fare, anche se proviamo ora a percorrerla un'altro pò, insieme (per fortuna c'è Mike!).

Matrice multidimensionale.

Una ciliegia tira l'altra, e il passo successivo risponde alla domanda "Ma se invece che una sola colonna di dati (i cognomi) voglio gestire anche una seconda colonna (i nomi), cosa caspita devo fare?" Il bravo Mike anche stavolta mi aiuta: semplice, si usa una matrice "bidimensionale". Confesso che anche in questo caso il mio cervello ha sputacchiato un pò, prima di mettersi in moto, infatti Mike per spiegarmi come si usano matrici multidimensionali, mi scrive:

  • ..stesso discorso per le matrici a più dimensioni:

    A(1,1)="Mario": A(1,2)="D'Ambrosio"

    A(2,1)="Giovanni": A(2,2)="Di Girolamo"

    A(3,1)="Giuseppe": A(3,2)="Mazzini"

     

    ..Se oltre al nome e cognome avessimo anche la città, avremmo:

    A(1,1)="Mario": A(1,2)="D'Ambrosio": A(1,3)=”Roma”

    A(2,1)="Giovanni": A(2,2)="Di Girolamo": A(2,3)=”Torino”

    A(3,1)="Giuseppe": A(3,2)="Mazzini": A(3,3)=”Roma”

dove si desume che per indicare cosa vogliamo da una matrice multidimensionale si indica accanto al nome della matrice (A in questo caso), due numeri separati da una virgola: il primo numero si riferisce al numero indice (di riga, per meglio capire), il secondo numero si riferisce, come se fosse una tabella,  alla posizione relativa alla colonna (virtuale) . Se quindi, con l'esempio sopra, si chiedesse il risultato di A(2, 3) vorremmo il dato che si trova sulla riga 2, terza colonna, ed otterremo "Torino".

Già, ma come la imposto una matrice a 3 colonne? Cosa devo scrivere come dichiarazione nella variabile per indicare che voglio una matrice a tre colonne? Devo scrivere 3 numeri? O cos'altro? Poi finalmente si è accesa un'altra lampadina: come faccio su un foglio di lavoro a indicare che voglio scorrere tre colonne? Uso un ciclo For Next che parte da 1 ed arriva a 3, una cosa così: For pippo = 1 To 3, cioè uso solo due numeri: 1 (il limite inferiore del ciclo) e 3 (il limite superiore del ciclo), e se poi voglio scorrere anche le righe uso un'altro ciclo che mi consentirà di scorrere tutta una tabella.

In una matrice multidimensionale avviene lo stesso e quindi  la dichiarazione dei numeri può avvenire indicando solo due valori, il primo indicherà il numero di righe massimo, il secondo il numero di colonne massimo che dovrà contenere la matrice, infatti, ove omesso, il numero iniziale sarà sempre zero, sia per le righe sia per le colonne; si useranno poi due cicli For Next che scorreranno i dati da prelevare e mettere in matrice. Se io dichiaro una matrice: Dim RIS(10, 3) imposto una matrice che conterrà 10*3 = 30 valori; sono i cicli For Next che leggendo le 10 righe di una tabella e le 3 colonne, assegneranno i dati alla matrice. A questo punto si capiscono meglio le istruzioni date da Mike. Supponiamo quindi di avere una tabella del genere:

Abbiamo "Cognomi" in A, "nomi" in B, "città" in C. Vorremo prendere tutti questi dati ed ordinarli alfabeticamente, copiandoli in altra destinazione (ma potremo filtrarli, o farci altre cose..). Appare evidente che dovremo "spostare" nell'ordinamento, il nome e la città insieme al Cognome. Faremo quindi come ci ha insegnato Mike, prima comporremo la matrice in memoria, poi la ordineremo, quindi la copieremo a destinazione.

Questa volta uso la variabile RIS (come "risultanza") per indicare il nome della matrice; poi, siccome userò la variabile "X" come contatore sia nel ciclo che assegnerà alla matrice i valori contenuti nelle celle, sia perchè userò la stessa "X" nella definizione di quale riga scorrere nella sintassi Cells(X, Y), avrò bisogno che l'indice nella matrice non inizi da zero (non esiste infatti una Cells(0, 0)) ma inizi da 1; per questo uso l'istruzione Option Base 1 posta nella sezione Generale-dichiarazioni del modulo che contiene la macro. E questo il primo gruppo di istruzioni:

Sub Peppo()
'carico in memoria la matrice, e non dichiaro (Dim) nessuna variabile; saranno tutte considerate di tipo Variant.
W = [A1].End(xlDown).Row 
'con la variabile "W" ottengo la lunghezza della tabella (il numero dell'ultima riga 'occupata).
ReDim RIS(W, 3)
'ora uso l'istruzione ReDim per il dimensionamento della matrice, che sarà composta da W*3 'elementi - W mi darà il numero di quante righe scorrere, e 3 sono le colonne.

'sotto: ora inizio un doppio ciclo che scorrerà per ogni riga (X) , tutte le colonne attraverso il secondo ciclo (Y), 'fino all'ultima riga
For X = 1 To W
For Y = 1 To 3

'per ogni ciclo la matrice RIS, nella posizione (X, Y) memorizza i dati contenuti nella cella (X, Y), quindi avremo 'all'inizio che RIS sarà uguale a RIS(1, 1) e quindi questa posizione in memoria sarà uguale al valore nella cella (1, 1) cioè "pippo", poi si passa a RIS(1, 2), uguale alla cella (1, 2) cioè "caruso", poi si passa a RIS(1, 3), uguale alla 'cella (1, 3) cioè "pisa"; quando termina il secondo ciclo interno, si ritorna al primo ciclo che questa volta sarà 'RIS(2, 1), uguale alla cella (2, 1) cioè "peppo", e così procede fino al termine dei cicli.
RIS(X, Y) = Sheets(1).Cells(X, Y).Value
Next
Next

....segue

a questo punto della macro, avremo in memoria tutta la nostra tabella, e starà lì, pronta ad essere usata. Ora vediamo di sfruttare l'idea che mi ha insegnato Mike per mettere in ordine la matrice; l'idea va necessariamente adattata, ma direi a questo punto che non ci sono grossi problemi: dovremo comparare solo i "cognomi" e nel caso di uno spostamento, spostiamo il cognome e insieme il nome e la città usando due variabili in più, così:

' metto in ordine la matrice, le spiegazioni iniziali sono le stesse dell'altra vista sopra.
For A = LBound(RIS) To UBound(RIS) - 1
For B = A + 1 To UBound(RIS)

'sotto: per mettere in ordine alfabetico la matrice ora dobbiamo confrontare il primo "cognome" che si troverà nella 'matrice nella posizione indicata dal contatore A (quindi primo elemento della prima riga, e prima colonna (virtuale) 'indicata con 1 (alla seconda colonna avremmo il nome, e nella terza avremmo la città relativi alla prima riga), e li 'confrontiamo col secondo cognome ottenuto da B (A+1), nel caso A sia maggiore di B, dovremo spostare in 'contemporanea cognome,nome,città reperiti con le variabili C, D, E, e quindi spostiamo i tre dati, come spiegato 'nella macro sopra.
If RIS(A, 1) > RIS(B, 1) Then
C = RIS(A, 1)
D = RIS(A, 2)
E = RIS(A, 3)
RIS(A, 1) = RIS(B, 1)
RIS(A, 2) = RIS(B, 2)
RIS(A, 3) = RIS(B, 3)
RIS(B, 1) = C
RIS(B, 2) = D
RIS(B, 3) = E
End If
Next
Next

....segue

Mike sarà sicuramente soddisfatto (io pure) nel vedere che le sue spiegazioni sono state finalmente assimilate. Ora basterà decidere cosa fare della matrice ordinata, per ora imposto le istruzioni che copieranno i valori in matrice in una'altra parte del foglio; vediamo un pò come avviene:

......da segue

riga = 1  'si assegna da quale riga sul foglio iniziare a copiare
For n = LBound(RIS) To UBound(RIS)
'con il contatore "n" scorriamo tutti gli indici della matrice; attenzione: 'NON tutti gli elementi della matrice, ma solo le righe, per intenderci, e ricordo che ora, l'indice iniziale della 'matrice parte da 1 (Option Base 1)

'quindi si rendono le Celle, riga1, colonna 5, 6, 7 uguali a:
Cells(riga, 5) = RIS(n, 1) 
'cognome n
Cells(riga, 6) = RIS(n, 2)
 'nome n
Cells(riga, 7) = RIS(n, 3)
 'città n
riga = riga + 1 
' si passa alla riga successiva fino alla fine del ciclo
Next

Erase RIS 
'ora con Erase si svuota la matrice dalla memoria (se sarà nelle nostre intenzioni svuotarla)
End Sub

 

L'istruzione Erase, che non conoscevo, (Mike mi ha suggerito), serve a svuotare una matrice dinamica. Questa è una nota tratta dalla guida in linea: "L'istruzione Erase consente di liberare la memoria utilizzata dalle matrici dinamiche. Prima che il programma possa di nuovo fare riferimento alla matrice dinamica, è necessario dichiarare nuovamente le dimensioni delle variabili matrice tramite l'istruzione ReDim".

Vi conviene, se interessati, leggervi le spiegazioni nei due articoli di Mike riportati in testa per capire la differenza tra matrici statiche e dinamiche.

Io avrei finito; chiedo scusa a chi le matrici le conosce bene, per imprecisioni che avrò commesso in questo articolo, ma mi sembrava un buon aiuto fare partecipi altri "del come" sono arrivato a "cominciare" a capire le matrici.

In attesa che le due lampadine diventino una luminara, auguro a tutti buon lavoro.

prelevato sul sito www.ennius.altervista.org