Newsgroup: it.comp.lang.pascal
Titolo: Dimensioni matrice: solo costanti?

Pensavo che quando si intende usare lo heap per gestire i propri dati fosse
possibile dichiarare una matrice usando delle variabili per indicare le
dimensioni, per esempio myarray[1..mymax], invece sono costretto a usare
delle costanti.
C'è qualche guru che mi sa spiegare come fare?
Grazie delle informazioni.                             Paolo Cortelli


wrote:

A) Io sono un guru?
B) Le matrici (PS quella che hai diciarato te non è teoricamente una
matrice ma un vettore, piccola la differenza...) e i vettori sono
delle strotture standard statiche... per fare quello che vuoi devi
fare una lista o se vuoi + flessibilita un bel albero... ma se non hai
ancora studiato i puntatori devi metterti l'animo in pace...
C) conosci puntatori? Come stai messo con Liste e Alberi?
---
Il Razziatore,
The Only Good Windows in an uninstalled Windows
-----------------------------------------------
E-MAIL: 
razzi...@usa.net
WEB   : 
razziatore.dsx.org
ICQ   : 67552596

 programma mandandolo magari in crash?
Esattamente non lo so, ma mi pare che sia un sistema troppo artificioso e
poco affidabile. Con i pc ultrapotenti che esistono oggi credo che non abbia
più molto senso complicare tanto i programmi (col rischio di ridurne
l'affidabilità) per risparmiare pochi byte di memoria.
Io sono il tipo che utilizza matrici statiche e fa poco uso della ricorsione
non per incapacità ma perchè l'allocazione dinamica e la ricorsione, se non
utilizzati in maniera molto oculata e quando veramente indispensabili, non
migliorano affatto l'affidabilità di un programma ma la peggiorano
notevolmente.
Siccome chi acquista un programma non vuole vedere quanto siano eleganti i
sorgenti (credo che di questo non gliene f**ta un tubo) ma vuole un prodotto
veloce e affidabile è bene andarci coi piedi di piombo con certe
sofisticherie.
Saluti, Marco ;)

     MyDinArray = ^MyArray ;


delle costanti.
Dipende da quale ambiente di sviluppo utilizzi (TP ? Delphi ?).
In TP, per esempio, e' possibile abolire il range checking e costruire
un array di dimensioni variabili a run-time.  Delphi gestisce gli
array dinamici.  In Pascal standard questa cosa non si puo' fare.
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

puntatori (allocazione dinamica della memoria);
In TP si puo' ridimensionare la dimensione di un array utilizzando un
puntatore a un array di 0 elementi (bisogna pero' disabilitare il
range-checking).
{$R-}
type MyArray = array [0..0] of Byte ;
     MyDinArray = ^MyArray ;
--


>Le matrici (PS quella che hai diciarato te non è teoricamente una
matrice ma un vettore, piccola la differenza...)
Comunque un vettore si può anche definire matrice senza problemi poichè si
tratta di una matrice ad una sola dimensione (matrice monodimensionale); su
molti libri infatti la parola vettori non compare e vettori e matrici
vengono comunque definiti allo stesso modo. In alcuni linguaggi è
addirittura anche possibile definire matrici tridimensionali (o matrici
cubiche) ;).
In ogni caso non è possibile in alcun modo variare in TP la dimensione di un
array in fase di esecuzione del programma a patto di non utilizzare i
puntatori (allocazione dinamica della memoria); imho, spaccarsi in due per
realizzare programmi che fanno uso dei puntatori (liste, pile, ecc...)
spesso non serve proprio a nulla se non a complicare di parecchio i
programmi :(
Saluti, Marco



Ne' liste ne'alberi ma solo puntatori e l'istruzione GetMem, ecco il
codice base per allocare matrici dinamiche sull'heap:
PROGRAM CibiribiKodak;
CONST
  mymax = 1000;
TYPE
  tipo  = REAL;
  vett  = ARRAY[1..mymax] OF tipo;
  myvett = ^vett;
  matr  = ARRAY[1..mymax] OF myvett;
  mymatr = ^matr;
VAR
   tab : mymatr;
PROCEDURE CreaMatr(VAR m : mymatr; dim : INTEGER);
VAR
  i                   : INTEGER;
  sp1,sp2,spt : LONGINT;
BEGIN
  sp1:=dim*SIZEOF(myvett);
  sp2:=dim*SIZEOF(tipo);
  spt:=sp1+dim*sp2;
  IF spt>MAXAVAIL THEN
    m:=NIL (*se non c'e' spazio assegna il puntatore a nullo*)
  ELSE
    BEGIN
      GETMEM(m,sp1);
      FOR i:=1 TO dim DO
        BEGIN
          GETMEM(m^[i],sp2);
          FILLCHAR(m^[i]^,sp2,0); (*pone a zero tutti i valori*)
        END;
    END;
END;
BEGIN
  CreaMatr(tab,2);
  (*esempio di assegnazione della matrice*)
  tab^[1]^[1]:=1.0;
  tab^[1]^[2]:=2.0;
  tab^[2]^[1]:=3.0;
  tab^[2]^[2]:=4.0;
END.  
"Non siamo altro che aggregati di polvere di stelle che si interrogano
sul funzionamenento degli astri del firmameneto" - Carl Sagan.

programma mandandolo magari in crash?
Assolutamente no, se si ha cura di allocare abbastanza memoria per il
puntatore.


sofisticherie.
Spesso chi acquista i programmi, ne acquista anche i sorgenti, quindi
non essere cosi' sicuro che tu abbia liberta' di usare tutto cio' che
vuoi nei tuoi programmi.


puntatore.
Si' allora sono d'accordo, ma allocare un puntatore per un numero
grande di bytes e poi ridefinire al suo interno la dimensione della
matrice non serve a risparmiare memoria (che e' un motivo per cui si
ricorre all'allocazione dinamica) e complica la gestione senza scopo,
tanto vale dichiarare una matrice normale (sempre che non ci siano
altri motivi per usare il puntatore).

 altri motivi per usare il puntatore).
Concordo al 100%
Saluti, Marco ;)

Concordo al 100%
Evidentemente anche tu non hai capito come si usa il costrutto
esposto.


altri motivi per usare il puntatore).
Niente affatto.  Rileggi il mio messaggio.
Cerca di usare quel costrutto e vedrai che il risparmio di memoria
c'e' eccome.


codice base per allocare matrici dinamiche sull'heap:
E se voglio allocare piu' di 1000 valori ?


 sono bravi in matematica e quelli che non lo sono."
Semplicemente aumenti il valore di mymax purche' sia minore del
massimo valore ammesso dal TP per il numero di elementi di un vettore;
se necessario poi aumenti l'heap con la direttiva {$M}.


Penso di essere io a non capire pero'... dopo il tuo codice devi
allocare il puntatore MyDinArray con un'istruzione NEW (1) o GETMEM
(2) o usare semplicemente il puntatore (3).
Quindi:
- se (1) il compilatore assegna un'area di 0 bytes per il puntatore e
se provi ad andare oltre il limite, per esempio assegnando
MyDinArray^[1]:=10;
(possibile visto che il range cecking e' disabilitato) rischi di
sovrascrivere un'area di memoria che era gia' occupata e causare
problemi al programma,
- se (2) devi specificare il numero di bytes che vuoi allocare e in
questo caso puoi usare un numero di elemento del vettore in modo che
sia (num. max. elemento * sizeof(Byte) <= bytes allocati) pena lo
stesso errore in (1),
- se (3) il compilatore non riserva alcuna memoria per il puntatore e
se lo usi incorri sempre nell'errore in (1).
Ho fatto una fatica immensa a scrivere tutto cio', spero di aver
chiarito quello che volevo dire... Byez

stesso errore in (1),
Quando si ha a che fare con la memoria dinamica e' cosi'.
In questo caso, entra in gioco lo stesso meccanismo dei puntatori in
C.  Pericoloso, ma conveniente.  Nel 1987 scrissi in TP 3.01 una
libreria di allocazione/deallocazione di matrici dinamiche per un
programma di matematica.  Ti assicuro che questo sistema funzionava
egregiamente e consentiva di utilizzare la sola memoria richiesta.

egregiamente e consentiva di utilizzare la sola memoria richiesta.
Okkidei allora mi fido, se  hai ancora quella libreria magari postala
qui nel NG che magari puo' servire. Byez.

se necessario poi aumenti l'heap con la direttiva {$M}.
Evidentemente la domanda non era chiara.
Se non conosco a priori il valore massimo gestibile, non posso neanche
impostarlo a tempo di progettazione.

Quando non conosci a priori la dimension dell'array che vuoi utilizzare
l'unica soluzione che ti rimane č.... usare una lista a puntatori !!
Byez
Visita il mio sito 
http://spazioweb.inwind.it/richiair/home.htm

l'unica soluzione che ti rimane č.... usare una lista a puntatori !!
Vedi il mio esempio + sotto di utilizzo di un puntatore ad un vettore
di dimensione 0.