Newsgroup: it.comp.lang.delphi
Titolo: Problema con ciclo for

Utilizzo spesso 
delphibasics.co.uk
 come riferimento perchè trovo la
consultazione dell'Help di Delphi molto difficoltosa, quindi mi scuso
se non riesco a far riferimento direttamente al manuale.
Leggendo su 
delphibasics.co.uk
 il ciclo for è definito così (tra le
altre definizioni):
for Variable := Integer Expression to|downto Integer Expression do
Statement;
a Variable viene dato inizialmente il valore della prima espressione
e, se il risultato è minore o uguale al risultato della seconda
Expression (quando è specificato to) allora Statement viene eseguito.
Variable viene incrementato di 1 ed il processo è ripetuto fino a
quando il valore di Variable è strettamente maggiore della seconda
Expression.
Ma cosa succede se in Statement c'è qualcosa che influisce su
Expression e ne cambia il valore? Sembra che il compilatore valuti
Expression alla prima esecuzione del ciclo for e poi mantenga il
valore iniziale, altrimenti non si spiegherebbe come mai il seguente
codice viene eseguito anche per valori di Varaiable maggiori della
seconda Expression:
  Utensili_file : TObjectlist;
  ...
  for j := i+1 to Utensili_file.Count - 1 do
  begin
    if (... espressione ...) then  utensili_file.Delete(j);
  end;
Esiste effettivamente il "problema" o mi sfugge qualcosa? Come posso
aggirare l'ostacolo?
Grazie
Francesco

devi fare il ciclo al contrario
A.


Il problema non sussiste perch� la variabile J � indipendente dallo 
statement.
Per essere dipendente, il valore della variabile J avrebbe dovuto subire 
delle alterazioni dentro il blocco begin....end.
 


Si infatti ma questo per una questione strettamente legata alle liste; 
perch� i riferimenti alle liste partono da n e finiscono a 1 e non da 1 per 
finire a n.
 

 finire a n.
Non capisco cosa intendi dicendo che i riferimenti alle liste partono
da n e finiscono a 1 ...
Per quanto riguarda il ciclo FOR, sto usando Delphi 2010, quindi, che
io sappia, dovrebbe avere l'ultimo compilatore disponibile. Ciò che
viene cambiato all'interno del ciclo è il valore Utensili_file.Count
che fa parte dell'espressione di controllo che, evidentemente, viene
valutata solo una volta all'inizio del ciclo.
Ho comunque risolto con un ciclo while dopo aver letto in "Essential
Pascal" di preferire il ciclo while nel caso di condizioni più
complesse.
  j := i + 1;
  while j < Utensili_file.Count do
    begin
      if (... espressione ...) then
        utensili_file.Delete(j);
      ...
      j := j+1;
    end;
Grazie


Il ciclo for � indicato SOLO quando si conosce in anticipo il numero di 
iterazioni e soprattutto quando queste devono essere fatte tutte quante; in 
tutti gli altri casi si usano le altre strutture condizioni a disposizione.
 

 quante.....
Non necessariamente.
All'interno di un for quando si soddisfa la condizione richiesta si pu� 
uscire con un break per velocizzare.
Ciao
Andrea 

 ha scritto nel messaggio 
news:4b477704$0$1131$4faf...@reader1.news.tin.it...

Il break c'� per una questione di compatibilit� con le vecchie versioni; ma 
un buon programmatore deve o dovrebbe usare le strutture cicliche, 
condizioni giuste al momento giusto.
Il fatto che ci sia un break nel for � irrilevante.
 

> Il fatto che ci sia un break nel for � irrilevante.
Non � cos�.
Se faccio un ciclo da 1 a 10000 e trovo la condizione che cerco all'item n. 
3 con il break esco dal ciclo, anzich� arrivare fino a 10000
Non � proprio una cosa da poco.
Andrea 

 ha scritto nel messaggio 
news:4b483a78$0$1108$4faf...@reader4.news.tin.it...

Usa direttamente un while o un repeat.
Per trovarti nella condizione che cerchi necessariamente ci deve essere un 
if...then... allora a questo punto usi un while se la condizione pu� 
verificarsi ancor prima che abbia inizio un ciclo oppure un repeat se sei 
sicuro che la condizione possa verificarsi soltanto in un momento 
successivo.
Al peggio il ciclo while o repeat sar� ripetuto 10.000 volte.
Usare il break � come usare il goto, insomma cattiva programmazione.
 

 finire a n.
Tu stai prp male, eh?
A.

> Il break c'è per una questione di compatibilità con le vecchie versioni
mi posti la fonte di questa perla di saggezza?
A.

Usare il break � come usare il goto, insomma cattiva programmazione.
ok per il while, il concetto � giusto.
Il punto era per� se con il for sono obbligato o meno ad arrivare alla fine 
del ciclo, IMHO non sono affatto obbligato ed esco con il break quando 
ottengo ci� che mi serve.
sul fatto che l'uso del break sia "cattiva programmazione" non mi trovi 
affatto d'accordo...
Andrea 

 ha scritto nel messaggio 
news:4b4861e1$0$1107$4faf...@reader4.news.tin.it...

Perch� allora ci sono i costrutti while e repeat; se va bene il for per 
uscire quando non � piu necessario continuare che senso ha utilizzare gli 
altri?
E' un po' come dire:
liste : array = (while & repeat) : for
 

 condizioni giuste al momento giusto.
Dove hai letto questa cosa?
A me non risulta proprio...
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

 A me non risulta proprio...
Per il fatto della "compatibilit�" basta andare indietro nel tempo, prima 
degli inizi della programmazione strutturata. Vero che il pascal � nato come 
linguaggio strutturato, ma � anche vero che prima di allora le strutture 
cicliche repeat, while, do loop etc  etc etc non c'erano e quindi si aveva 
l'esigenza di uscire da un ciclo for anche prima del suo completamento... e 
da qui fu introdotto il break; proprio come il goto.
In pascal infatti tramite le etichette e il goto potevi anche saltare da un 
punto a un altro del programma tipo cosi:
begin
a := 0
miaetichetta:     if a < 5 then
                             begin
                                .........
                                a := a + 1
                                goto miaetichetta;
                             end;
end.
Che poi equivale a:
a := 0;
while a < 5 do
  begin
     ............
     a := a + 1;
  end;
Poi con l'introduzione delle strutture cicliche tipo repeat, while e altre 
poco per volta si � teso a eliminare l'uso improprio di istruzioni tipo il 
break, il goto etc .
Insomma per rispondere alla tua domanda basta andare indietro nel tempo 
prima dell'avvento della programmazione strutturata, prima che fossero 
introdotte le strutture repeat, while etc.
Li a quel tempo l'unica struttura ciclica era il for e l'unica condizionale 
l'if... e quindi   le strutture tipo repeat, while, do loop etc erano 
simulate attraverso etichette, break, goto etc etc.
Per questo dal punto di vista didattico oggi che ci sono le strutture 
apposite si invita a usare quelle anzich� andare ritornare ai primordi; 
nessuno lo vieta ma � come la questione delle liste: meglio usare un array o 
una lista?
Se ricordi io qualche giorno fa dicevo che era meglio usare un array eppure 
qualcun altro sosteneva che era meglio usare le liste... allo stesso modo... 
se ci sono strutture predisposte a uno scopo ben preciso come il while, il 
repeat,  che ti permettono di uscire da un ciclo appena una condizione � 
vera o falsa... non ha senso usare una struttura che per natura tende a 
effettuare tutti gli N cicli FORZANDOLA a uscire dal ciclo al verificarsi di 
una condizione.
Se uno vuole usare il break nel for pu� farlo, ma a questo punto perch� non 
tornare allora alle etichette e al goto per simulare un for? :)
Come vedi il discorso non avrebbe senso. Certo uno pu� usare tutti i break 
che vuole esattamente come uno pu� usare tutti gli array o tutte le liste 
che vuole; � liberissimo di farlo; ma ogni strumento va usato nel modo 
giusto e su questo sono certo che anche tu concordi.
 

 altri?
Perch� di solito i linguaggi di programmazione sono ridondanti. In C, per
esempio, la somiglianza tra for e while � talmente forte che, volendo,
puoi usare solo il for.
La domanda che dovresti porti �: se il for fosse sufficiente a fare tutto,
perch� esiste il break e l'istruzione goto?
Non di certo per compatibilit� all'indietro.
Il tuo concetto secondo cui il "bravo programmatore" non usa l'istruzione
break non � corretto. Il break pu� servire a risparmiare cicli macchina,
esattamente (e la cosa ti sorprender�) come il goto. Il goto esiste ancora
perch� � il metodo pi� efficiente per uscire dai cicli pi� interni, quando
esistono molti cicli innestati. Ovvio che pu� essere evitato nella
stragrande maggioranza dei casi, ma ci sono casi il cui serve e non pu�
essere rimpiazzato da nient'altro.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Se ricordi io qualche giorno fa dicevo che era meglio usare un array[...]
E dicevi una cosa errata. E continui a dire cose errate in questo thread.
Ho cercato di farti capire le ragioni per cui usare la lista, in quel
caso, � di gran lunga meglio che usare un array. Ed ora fai il piacere di
capire che break e goto SERVONO, non sono ridondanti e non sono
sostituibili dalle condizioni di uscita di cui parli. Costruisci dieci
cicli innestati e poi trova un modo pi� efficiente del goto, coi tuoi
metodi, per uscire dal pi� interno.


 finire a n.
Eh??!...


 liste; 
Eh?... che intendi per "puntatore di riferimento"?



Dal libro di Nicklaus Wirth se ho scritto bene perch� il libro non l'ho a 
portata di mano, una struttura dinamica ha due puntatori il primo che 
rappresenta quello di origine da cui � possibile accedere al primo elemento 
della lista e il secondo l'elemento corrente quindi anche l'ultimo elemento 
della lista.
Quando si aggiunge un elemento non si scorre tutta la lista per andare a 
trovare l'ultimo elemento della lista ma si salta direttamente all'ultimo 
elemento della lista per mezzo del secondo puntatore puntatore.
Se si elimina il primo elemento della lista si perde il riferimento 
all'elemento successivo della lista e quindi diventa impossibile accedere al 
resto degli elementi.
Per questo motivo non si pu� cancellare il primo elemento della lista e via 
via tutti gli altri da 1 a N.... ma si deve procedere a ritroso... partendo 
dall'ultimo elemento o comunque da un elemento diverso dal primo.
Puntando all'ultimo elemento della lista infatti puoi eliminarlo senza 
compromettere quello precedente; allo stesso modo se elimini un elemento 
centrale della lista  esempio l'elemento N-3 il puntatore della lista N-4 
punter� direttamente all'elemento N-2.
 

I casi sono 2:
1) sei un troll
2) sei veramente convinto delle cose che scrivi.
A.


Forse � pi� corretto dire: "delle cose che insegnano"; di certo non le 
invento io.
In ogni caso; se quanto scrivo � sbagliato (eh mica sono perfetto, mi limito 
ad esporre ci� che mi � stato insegnato) almeno correggimi con 
argomentazioni valide e supportate; non chiedo ci� per fare polemica ma 
semplicemente per essere messo in condizione di correggermi nel caso in cui 
certi concetti che mi hanno trasmesso siano errati.
Per�, se questi concetti non sono errati, allora perch� mi contesti; non 
voglio avere la presunzione di dire la cosa giusta, non sia mai... ma 
nemmeno voglio che mi sia detto che quanto ho scritto � sbagliato senza 
alcuna argomentazione valida e supportata; ma solo perch� sei tu a dirlo.
Non penso di chiedere la luna ma appena il giusto. Se non hai voglia di 
argomentare a parole tue, nulla di strano, ma almeno dammi qualche link che 
supporta ci� che sostieni meglio se una fonte attendibile.
 

 via via tutti gli altri da 1 a N.... ma si deve procedere a ritroso... 
Non � cos�. Il procedimento a ritroso serve solo in quei casi in cui si
itera sulla lista usando un indice, perch� cancellando sul posto si
invalidano gli indici successivi. Andando all'indietro, invece, gli indici
precedenti non vengono invalidati. Ma questa non � una regola generale per
la cancellazione degli elementi.


 che supporta ci� che sostieni meglio se una fonte attendibile.
Argomentare � molto semplice: personalmente, non ho mai sentito n� letto 
n� studiato che il Break sia qualcosa progettato per compatibilit� 
all'indietro o sconsigliato nell'uso all'interno dei cicli, come 
sostieni tu, pertanto sono portato a pensare che questo non sia vero.
Sei tu che affermi il contrario, pertanto dacci tu la fonte di questa 
informazione che ci � sfuggita.
E' comoda ribaltare la frittata... :)



Lungi da me l'intenzione di girare la frittata, come hai potuto vedere 
sopra, ti ho argomentato e citato degli esempi frutto di un mio 
ragionamento.
 

 oppure "non buona programmazione" quando si fa ricorso al break o al goto, 
Non sai di cosa parli.



Ho dimenticato di aggiungere un altro dettaglio.
Il pascal � stato sviluppato molto tempo dopo rispetto al basic e molte 
caratteristiche del basic sono stata ereditate dal pascal per favorire 
eventualmente la portabilit� del codice dal basic al pascal introducendo al 
tempo stesso il concetto di programmazione strutturata; il pascal infatti � 
nato come linguaggio strutturato.
Il basic guardacaso ha proprio le istruzioni break e goto; tuttavia il basic 
di quel periodo non disponeva ancora di strutture di controllo tipo while/do 
o repeat/untile per cui si era costretti a far uso di etichette (i famosi 
numeri di linea del basic) e di istruzioni come goto e break.
 


Non per polemica, lungi da me questa intenzione, ma per convincimento, ti 
posso chiedere un esempio pratico in cui l'uso del break (in questo caso) o 
del goto, siano indispensabili e non se ne pu� fare a meno?
La mia intenzione sarebbe quella di dimostrare come una circostanza di quel 
tipo possa essere scritta nell'equivalente senza l'uso del goto/break.
Se riesco in questa intenzione l'espressione da te usata come:   "quelle 
istruzioni servono" diventerebbe falsa e quindi ti dimostrerei che se ne pu� 
sempre fare a meno;  in caso contrario mi convincer� effettivamente del 
fatto che hai ragione e che in certe circostanze non se ne pu� proprio fare 
a meno.
Come vedi in questa richiesta non c'� malizia, ma semplicemente voglia di 
apprendere perch� in tutta la mia vita, sinceramente non mi sono mai e dico 
mai mai mai trovato nelle condizioni di dover utilizzare espressamente il 
goto o il break o il continue etc etc etc.
Quindi approfittando di questa occasione che se ne sta parlando voglio 
trovarmi in una situazione di quel tipo (in cui sicuramente tu ti sarai 
trovato, per affermare che servono) per capire quali effettivamente siano i 
limiti delle strutture di controllo come il while/do o repeat/until.
Grazie ancora.
Cooper.
 

 .....
Togliere un istruzione dal set base ?? mmmm
cmq secondo me ti stai confondendo con "deprecated" che non è riferito 
al set base di istruzioni, ma a specifiche funzioni di classi come per 
esempio la funzione GetBookmarkStr la quale è definita deprecated (D2010 
Unit DB riga 2412) ossia in disuso(non so se il termine è corretto ma 
credo renda l'idea) e da una versione all'altra potrebbe essere rimossa.
-- 
Ibis et redibis non morieris in bello
http://goblinland.myminicity.com/


No, io ho fatto un esempio ben preciso; e cio� cosa sarebbe successo se gli 
sviluppatori di delphi da oggi a domani avessero rimosso le parole chiavi 
goto e break.
Io ritengo che la conseguenza sarebbe stata la necessit� di dover riscrivere 
il vecchio codice che usa goto e break ricorrendo alle strutture while/do e 
repeat/until; ma non per questo si sarebbe venuti a trovare nelle condizioni 
tali da non poter pi� scrivere del codice equivalente senza quelle 
istruzioni.
Prova a immaginare questo scenario.
Finch� non viene dimostrata l'indispensabilit� delle istruzioni goto e/o 
break (ovvero viene posta in evidenza una circostanza tale in cui le 
istruzioni goto e/o break non possono essere sostituite da costrutti tipo: 
while/do   o repeat/until) io ritengo che il loro uso per quanto improprio � 
limitato ad una questione di mera comodit� e quindi di "cattiva abitudine".
Nel momento in cui viene dimostrata questa indispensabilit� allora appare 
chiaro che mi sbagliavo e di grosso anche.
 

 chiaro che mi sbagliavo e di grosso anche.
Per la "non essenzialit�" del GOTO e del BREAK (e dei loro corrispettivi
in 
qualsiasi altro linguaggio) esiste il teorema di Jacopini-B�hm (due 
italiani, tra l'altro) che lo dimostra.
Che siano inutili, per�, � un'altro discorso: per esempio, questo � uno
dei 
primi testi che cerca di dare una spiegazione del perch� possono servire
http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf
mentre questo � un'altro caso in cui sono necessari
http://en.wikipedia.org/wiki/Tail_call
Ciao
ACSH



Se il teorema di Jacopini-B�hm dimostra la "non essenzialit�" ho qualche 
dubbio sul fatto che possano essere necessari; forse necessari perch� usando 
strutture alternative si ottiene un risultato pi� complesso ma questo non 
significa che non si possa fare; significa solo che in quel caso specifico 
risulta pi� comodo farvi ricorso.
In ogni caso il link a cui fai riferimento analizza una situazione a basso 
livello. Dovremmo rimanere nell'ambito di un linguaggio ad alto livello 
quale il pascal (o delphi) il quale supporta strutture alternative che 
appunto permettono di fare a meno del GOTO e/o BREAK.
Per� se mi � sfuggito qualcosa sul ci� a cui ti riferivi in modo particolare 
ti sarei grato se mettessi meglio in evidenza il particolare che mi � 
sfuggito.
 

 La mia intenzione sarebbe quella di dimostrare come una circostanza di >quel
tipo possa essere scritta nell'equivalente senza l'uso del goto/break.
Bene. Sono curioso di vedere la tua soluzione.


 di quel periodo non disponeva ancora di strutture di controllo tipo while/do 
Questo lo dici tu. Il Basic possedeva eccome il WHILE/WEND. Informati.


 chiaro che mi sbagliavo e di grosso anche.
Bene: appare chiaro, allora.


 ricorrendo ad altre strutture create appositamente allo scopo.
NO. Stai semplicemente dimostrando che il linguaggio possiede costrutti
che hanno la stessa espressivit�, ma ci� non vuol certo dire che riesci a
fare le stesse cose, con la stessa efficienza.



Ti riferisci a tanti cicli for uno dentro l'altro? 


Le prime versioni no.  Il GwBasic per esempio non possedeva questi 
costrutti, mentre il QuickBasic si. Noi parliamo di un periodo precedente 
alla nascita del linguaggio pascal, non ad un periodo successivo.
Il pascal come linguaggio ha introdotto i principi della programmazione 
strutturata; ma prima di allora la programmazione era tipicamente "lineare".
 

 costrutti
Certo che ce li aveva.


 Ti riferisci a tanti cicli for uno dentro l'altro?
Fammi vedere la tua soluzione.



Ma su questo siamo pienamente d'accordo; se uno ha bisogno di performance, 
velocit� etc etc etc, pu� benissimo ricorrere all'assembly o comunque a 
strutture di basso livello appunto come il break e il goto.
E' lo stesso discorso che si faceva con le liste, se ho bisogno di 
risparmiare in dimensione e velocit�  uso gli array, non hanno la stessa 
comodit� delle liste ma mi permettono comunque di arrivare al risultato 
finale a vantaggio della dimensione dell'eseguibile e della velocit� di 
elaborazione.
L'uso delle liste infatti non faceva altro che incrementare la dimensione 
dell'eseguibile e al tempo stesso rallentarne il suo processo di 
elaborazione.
La stessa cosa si pu� dire per il while/repeat rispetto all'etichetta e il 
goto; ma questo non significa per� che il goto sia indispensabile... diventa 
indispensabile in una via di mezzo fra l'assembly e il pascal quando occorre 
una elaborazione dei dati veloce e una dimensione dell'eseguibile ridotta ai 
minimi termini o quasi. 


Tu metti in mezzo il discorso dell'efficienza; io non ho parlato di 
efficienza. Se uno vuole un codice efficiente, scrive direttamente in 
assembly.
Il fatto che il linguaggio possiede costrutti che hanno la stessa 
espressivit� nessuno lo mette in dubbio; ci� di cui si discute �, 
nell'ambito dei principi della programmazione strutturata, quanto � corretto 
usare istruzioni quali GOTO, BREAK, CONTINUE etc etc quando esistono 
costrutti appositamente creati allo scopo.
La risposta alla domanda �: secondo i principi della programmazione 
strutturata, l'uso delle istruzioni GOTO, BREAK, CONTINUE etc etc � errato. 
Che poi uno voglia rispettare tali principi o meno � un altro discorso.
Per� ci� che � certo � che non esistono situazioni tali in cui non � 
possibile fare a meno di istruzioni come GOTO e BREAK; questo per il teorema 
citato precedentemente. 


Il gwbasic sicuramente no :)
Controlla pure. Nel gwbasic si scrivera anteponendo il numero di linea 
all'istruzione vera e propria.
 


Prima dimmi a cosa ti riferivi in particolare; come faccio a darti la 
soluzione se non so l'esempio a cui ti riferivi; riguardo al for annidato 
chiedevo una conferma.
 

 goto; ma questo non significa per� che il goto sia indispensabile... 
Il goto � indispensabile in determinati casi. Smettila di dire sciocchezze.


 possibile fare a meno di istruzioni come GOTO e BREAK
Ma niente affatto. Non � cos�. Ti ho gi� citato almeno un caso in cui
usare il GOTO � indispensabile e non puoi sostituirlo con nient'altro.



Mi ricordo benissimo che "a quei tempi" usai proprio un ciclo WHILE ... 
WEND per caricare tutte le immagini di "Melissa" una donnina dello strip 
poker della Artwox ... :P
infatti ero sicuro .. piccola ricerca con google e 
http://www.antonis.de/qbebooks/gwbasman/index.html


 Controlla pure.
E invece ce li aveva eccome. Te lo ripeto per l'ennesima volta. Sei tu che
devi informarti. Da: 
http://en.wikipedia.org/wiki/GW-BASIC
"There is little support for structured programming in GW-BASIC. All
IF/THEN/ELSE conditional statements must be written on one line, although
WHILE/WEND statements may group multiple lines[...]"


 chiedevo una conferma.
Scrivi dieci for annidati e poi trova il modo pi� efficiente per uscire
dal pi� interno. Evidentemente, poi, Dennis Richie era poco informato
sulla programmazione strutturata, considerato che forn� il suo C del
"break" quale unico metodo per uscire da un costrutto "switch". Se ti
avesse conosciuto, forse avrebbe cambiato idea. O forse no.


 certi concetti che mi hanno trasmesso siano errati.
Sarai accontentato!
Riassumo brevemente le cose che hai scritto, anche in alcuni post
precedenti:
1) e' utile lavorare sul codice per ottenere un exe quanto piu'
piccolo possibile
2) il break e' obsoleto e lo usano solo quelli che lavorano male si
deve usare il while
3) i riferimenti alle liste partono da n e finiscono a 1 e non da 1
per finire a n
4) sintassi "native"
Mi auguro che alle tante parole, seguano fatti, nello specifico la
capacita di leggere in toto quanto scrivo e quella di mettere in
discussione il prp modo di lavorare e le prp convizioni, cosa che per
il 99% dell'umanita' risulta impresa titanica. Ma visti i tuoi skill,
di sicuro questo non sara' un problema, per te.
Sul punto (1), ripeto quanto detto nell'altro post, al quale non hai
*mai* risposto o ribattuto...
Questo e' un ulteriore segnale di "warning" per quanto riguarda il mio
pensare che tu sia un troll.
In sintesi: su windows, salvo forse windows mobile, il problema delle
dimensioni del file exe di fatto NON ESISTE.
Ovviamente, e' scontato, ma non per tutti, che ci possano essere casi
in cui la cosa puo' essere vincolante.
Un esempio era costituito ai tempi dei floppy da 1.44 megabytes....
Mo magari ti starai chiedendo xche il problema non sussiste.
Ma sono dannatamente convinto, vista la convinzione con la quale stai
difendendo i puoi discutibili punti di vista non ancora documentati,
che sarai sicuramente skillato su memoria segmentata, memoria
paginata, memoria virtuale, overlay e organizzazione top-down, modo
reale e modo protetto.
Quindi, adesso spiega *tu* a *me* xche il problema non sussiste.
Sul punto (2), il break...
a) visto quanto affermi, voglio, e sottolineo voglio, un link SERIO
nel quale qualcuno di affidabile scrive che il break su delphi e'
tenuto per retrocompatibilita.
b) visto che non parliamo di prodotti "artistici" ma di cose per
lavorare, vorrei che mi spiegassi che differenza esiste, oltre che da
un punto di vista puramente *formale*, tra un while dove esci per una
condizione esplicita e un for dove esci forzando tu l'uscita.
c) se il break e' cosi una latrina, viene da chiedersi come mai e'
stato comunque introdotto in linguaggi piu nuovi rispetto a c/c++,
basic e pascal...Ad esempio java  e c#.
Magari chi usa anche linguaggi di scripting come ruby e python potra'
dirci se anche essi hanno un costrutto del genere.
Ad esempio, fa seriamente riflettere il fatto che su python non sembra
esistere di fatto la distinzione private/protected/public etc..Ma ci
sarebbe veramente da ridere se ha il break, non trovi?
d) in base a quale criterio e' lecito scrivere codice
illeggibile,sporco (di quello che quando ci metti le mani per fare bug
fixing ti verrebbe di trovare chi l'ha scritto e impiccarlo..!) pur di
ridurre le dimensioni del file exe (vedi punto 1..) arrivando
addirittura a pensare di fare *copia e incolla di pezzi presi dalle
unit standard di delphi*, ma l'uso di break per uscire da un ciclo for
e' una cosa da "cattivi programmatori"?
Sul punto (3): " i riferimenti alle liste partono da n e finiscono a 1
e non da 1 per finire a n"
TList, e' una *collection*: ti permette l'accesso in base all'indice.
Qua puoi andare da sopra, da sotto, random, come ti pare.
Ovviamente (ma non per tutti, almeno la prima volta...) se devo fare
delle remove devo partire dall'ultimo...
Ma la cosa importante, e' che e' LA CLASSE che si occupa di gestire la
memoria necessaria, oltre a non richiedere a ME la scrittura di altro
codice...
Posso scrivere remove e fregramene.
Viceversa, se uso *array* devo spostare elementi facendo un ciclo e
poi ridemensionare l'array con setlength.
Posso scrivere IndexOf e fregarmene.
Viceversa, se uso array devo fare un ciclo ogni volta che devo cercare
un elemento.
Ah, si..Posso creare una funzione e richiamarla...e avere altro codice
appeso e sparso ovunque....
Ma usare quello che esiste, evitando di reiventare la ruota, pronto, e
sopratutto TESTATO da migliaia e migliaia di persone al mondo che
usano la stessa classe per fare migliaia di cose diverse, sara'
ovviamente essere un "cattivo programmatore"... Buttiamo via .net,
jee, hibernate, etc etc etc
TQueue è una *coda*, quindi ti permette SOLO un accesso FIFO (quindi
vai *solo* da 1 a n)
Poi ci sono le *pile*, che hanno SOLO un accesso LIFO (vai solo da n a
1).
Poi , ci sono le *liste*, dove ogni elemento ha almeno un riferimento
ad uno degli elementi adiacenti.
Adesso, per favore, mi spieghi a quale contesto si applica cio che
dici tu :
" i riferimenti alle liste partono da n e finiscono a 1 e non da 1 per
finire a n"
Punto (4): "Gli array sono nativi le classi no".
TU VUOI VERAMENTE CHE TI RISPONDA SU QUESTO PUNTO?
A.


Hai ragione, ricordavo male io, chiedo venia; allora andiamo ad una versione 
ancora pi� vecchia del basic, quella utilizzata nel commodore 64; 
evidentemente sono andato avanti nel tempo rispetto a quando � uscito il 
pascal col gwbasic.
Quello che alla fine voglio dire � che il basic come linguaggio � nato senza 
strutture cicliche eccezion fatta per il for.
 

 senza strutture cicliche eccezion fatta per il for.
Ti sbagli. Molte delle prime implementazioni Basic gi� possedevano i
DO..LOOP / DO..UNTIL / WHILE..WEND. D'altronde l'Algol 60, progenitore di
molti dei linguaggi strutturati a venire, possedeva gi� il while.



Qualcosa tipo cosi:
for a1 := x1 to y1 do
  for a2 := x2 to y2 do
    ........
      for a10 := x10 to y10 do
         begin
             if condizione then break;
         end;
Qualcosa di questo tipo intendi?
Posto che sia questa la condizione in esame, tu usciresti dall'ultimo ciclo 
al verificarsi della CONDIZIONE ma non dai primi nove; per cui l'ultimo 
ciclo continuer� ad essere eseguito fino al completamento dei cicli pi� 
esterni.
Al verificarsi della condizione per uscire da tutti i cicli dovresti mettere 
un break per ogni ciclo:
 
http://www.delphibasics.co.uk/RTL.asp?Name=Break
Dove dice: "It is important to note that the Break statement only jumps out 
of the current loop - not out of any nested loops above it. The Goto 
statement can. "
Quindi scriviamo:
for a1 := x1 to y1 do
  for a2 := x2 to y2 do
    ........
      for a10 := x10 to y10 do
         begin
             if condizione then goto miaetichetta;
         end;
miaetichetta:   istruzioni
Scrivendo cosi, uscirei da tutti i cicli e salterei direttamente a 
miaetichetta.
Nulla per� mi vieterebbe di scrivere:
while not condizione do
  begin
     blocco codice
  end;  x
Gestendo all'interno del blocco codice i valori che delle variabili da a1 ad 
.a10 andrebbero ad assumere e la condizione di uscita.
Alla fine un for del tipo:
for x := a to b do
  begin
     .......... {istruzioni} ..........
  end;
Si pu� sempre scrivere nella forma:
x := a;
While (x <> b) do
    Begin
       .......... {istruzioni} ..........
       x := x + 1;
    End;
Quindi dieci for annidati si potrebbero scrivere come dieci while annidati; 
inserendo nel while pi� interno una variabile booleana che da false passa a 
true; e riportando il valore di questa variabile booleana in tutti gli altri 
while pi� esterni al fine di uscire dal ciclo while pi� interno.
Il risultato sarebbe dover scrivere un numero di righe di codice molto pi� 
elevato (questo � vero) rispetto alla soluzione col for e goto; ma ci� non 
significa che non si possa fare; per cui sarebbe pi� corretto parlare di 
comodit� che di impossibilit�.
In effetti col for e goto in una situazione del genere, il goto risulta pi� 
comodo, ma non indispensabile visto che volendo si potrebbe utilizzare un 
altra forma (il while annidato) e raggiungere ugualmente il risultato senza 
ricorrere al goto.
 

 Nulla per� mi vieterebbe di scrivere:
<...>
E qui casca l'asino. Lo sapevo che avresti proposto questa soluzione.
E' ovvio che si pu� usare una variabile per ogni ciclo while, ma finisci
per implementare qualcosa di gran lunga meno efficiente del goto. La mia
richiesta era di implementare, a modo tuo, qualcosa che conservasse la
stessa efficienza. E cos� non �, nel tuo codice. Il goto, in questo caso,
non � affatto sostituibile. Non si tratta di riuscire a fare la stessa
cosa, si tratta riuscire a farla in maniera ugualmente efficiente. Come
vedi, il goto non � solo comodo, � indispensabile e il risultato che tu
raggiungi non � affatto equivalente.



Certo. Ma tutto � relazionato al livello di astrazione a cui si riferisce.
Una classe � scritta utilizzando istruzioni native del linguaggio (o pi� 
semplicemente un livello di astrazione pi� basso) mentre un array � gi� una 
struttura dati nativa del linguaggio, indipendentemente dal livello di 
astrazione.
Prendiamo la classe TLIST, essa prevede la funzione di ordinamento; ma 
l'algoritmo di ordinamento a sua volta fa ricorso a istruzioni native del 
linguaggio.
Ora per questo motivo una classe TLIST non � nativa del linguaggio; ma 
costituisce una estensione del linguaggio; che poi delphi l'ha sempre avuta 
fin dalla prima versione � un altro discorso; ma se andiamo alla versione 6 
o anche 7 del pascal (quindi ancor prima di delphi) considerando che la 
versione delphi 1.0 coincide con borland pascal 8.0...  osserviamo che la 
classe tlist ancora non c'era e insieme ad essa mancavano anche altre 
classi.
Per questo ho detto che le classi sono una estensione del linguaggio e che 
non sono native del linguaggio. Tanto � vero che tu puoi crearti tutte le 
classi che vuoi e aggiungerle al tuo linguaggio ma non per questo esse sono 
native del linguaggio, rimangono pur sempre una estensione.
Cmq ti sarei grato se anche tu mi dicessi il tuo punto di vista in merito.
 


A me non risulta, per� ammesso che sia come dici, perch� il basic del 
commodore 64 (o 16 o 128) o il vic 20... non avevano queste strutture? 
Eppure anche quelle erano versioni di basic.
Magari sono io che ricordo male... per� non mi sembra; visto che ho 
cominciato per diletto a programmare proprio usando il commodore.
 

 esplicitamente che lavoravo con la console, quindi in ambiente dos.
Questa � davvero grossa: la "console" non ha nulla a che fare con il "DOS".
Il resto del post non l'ho letto ...
Ciao
ACSH 
--- news://
freenews.netfront.net/
 - complaints: 
ne...@netfront.net
 ---


D'accordo, diventa indispensabile per una questione di comodit�; per� come 
hai visto anche tu, ho fornito una soluzione alternativa al problema senza 
ricorrere al goto.
Il discorso era nato sul fatto se si poteva fare a meno del goto oppure no. 
Togliendo la comodit�, e la praticit� abbiamo visto che � possibile fare a 
meno del goto arrivando a scrivere il codice in modo diverso quindi da 
questo punto di vista non � indispensabile perch� � sempre possibile 
ricorrere ad altri costrutti; da un altro punto di vista invece risulta 
comodo e pratico in altre situazioni altrimenti pi� complesse a livello di 
codice da scrivere e quindi meno pratico.
 

 Io non dico che siano inutili, dico solo che � possibile farne a meno.
Quindi perch� un ciclo "for" non lo ritieni altrettanto superfluo come 
"goto" e "break"?
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)


Il costrutto for, come il while, il repeat etc sono costrutti che derivano 
dal un costrutto base che � uguale per tutti e che varia solo nella 
condizione, un costrutto base composto semplicemente da: a) etichetta; b) 
struttura condizionale if then;  c) contatore oltre naturalmente al blocco 
istruzioni.
Questi operano su un livello di astrazione maggiore rispetto al goto.
Il nocciolo della questione era era possibile convertire un QUALSIASI blocco 
di codice con istruzione BREAK e/o GOTO in un blocco di codice SENZA 
istruzione BREAK e/o GOTO; la risposta � SI in virt� del teorema di Jacobin.
Che poi l'istruzione GOTO semplifica certe situazioni a scapito di altre 
questo � anche vero; in alcuni casi (come l'esempio di cicli annidati) � 
vero che consente l'uscita dal ciclo con minor numero di righe di codice ma 
al tempo stesso � altrettanto vero che esso non risulta indispensabile se 
non per una questione meramente pratica e comoda.
Nessuno infatti vieta di scrivere 50 righe di codice in pi� per non usare il 
goto, ma usando il goto si pu� evitare di scrivere 50 righe di codice in pi� 
e ottenere ugualmente lo stesso risultato.
Il punto per� � un altro; se si vogliono seguire le linee guida della 
programmazione strutturata, esse INVITANO ed evitare istruzioni come GOTO, 
BREAK e affini.
Da notare INVITANO e non VIETANO.
E' lo stesso discorso che si fa quando si scrive una pagina web XHTML; se 
non rispetti le linee guida del W3C per intero essa risultare non valida; se 
le rispetti tutte risultare valida; ma nessuno ti obbliga di scrivere una 
pagina perfettamente validata.
Per� una pagina validata ha i suoi vantaggi per quei browser che rispettano 
gli standard w3c.
Nel nostro caso il discorso � concettualmente identico.
Un programma scritto rigorosamente rispettando i cardini della 
programmazione strutturata � un programma senza istruzioni GOTO, BREAK, etc 
etc
Il motivo per cui � stata introdotta la programmazione strutturata � stato 
proprio finalizzato a rendere il codice pi� leggibile e lineare evitando di 
saltellare sopra e sotto come accadeva spesso col basic.
 

 BREAK e affini.
Ma chi te l'ha detto? *CHI* fa di questi inviti? fammelo conoscere.


 Magari sono io che ricordo male... per� non mi sembra
Ricordi male.


 ricorrere ad altri costrutti
Non è così. Il goto non è rimpiazzabile, nel caso specifico che ti ho
citato, con le strutture iterative alternative di cui parli. Non
"abbiamo visto" un bel niente. Continui a confondere l'esigenza di
SALTARE con l'esigenza di CICLARE. Sono due contesti separati e
distinti. Tutto ciò che, semmai, abbiamo visto è che continui a
insistere sulle tue sciocchezze senza capire quel che gli altri ti
stanno comunicando.

Anche se il thread ha preso tutta un'altra strada, penso sia meglio
postare qui un dubbio che mi è venuto riguardante il ciclo for (poi
trasformato in while) del primo post.
Stasera ho verificato che il grave problema che si verifica è che
cancellando un elemento dalla lista dall'interno del ciclo, a meno di
non decrementare di 1 l'indice (j nel mio caso) subito dopo, escludo
dal ciclo un elemento della lista! Che stolto!
  j := i + 1;
  while j < Utensili_file.Count do
    begin
      if (... espressione ...) then
        utensili_file.Delete(j);
      ...
      j := j+1;
    end;

 evitando di saltellare sopra e sotto come accadeva spesso col basic.
Posso saltellare di qua e di l� anche con semplici cicli WHILE, se 
voglio. La questione � concettuale.
Comunque sia, i sistemi si evolvono, e il GWBASIC lo abbiamo abbandonato 
da mo'... (spero) :)


 dell'elaborazione.
Magari quando hanno spiegato le classi avevi l'influenza.
A.

 Ma chi te l'ha detto? *CHI* fa di questi inviti? fammelo conoscere.
Quando studiavo OOP alle superiori col pascal, ricordo che gli 
insegnanti avevano *demonizzato* il goto vietandolo espressamente, 
citandolo come un'artefatto della programmazione strutturata, ecc.. :-O
Io credo che in quegli anni (inizi anni 90) non esistendo ancora in 
italia internet e tutto il fenomeno sociale dell'open source, ecc, gli 
insegnanti trasmettevano molti concetti puramente teorici/accademici 
frutto di un isolamento informatico che oggi non esiste piï¿œ.
Ricordo ad esempio che per un compito in classe di teoria dei sistemi 
ci era stato chiesto di scrivere un programma in assembler.. sul foglio 
a quadretti! Ricordo che ero impazzito a seguire mentalmente tutti i JZ 
JNZ.. insomma una cosa che oggi mi pare assurda.. eppure allora era 
cosï¿œ.
Nonostante questo, la nostra generazione ha imparato comunque a fare 
informatica, c'ï¿œ poi chi ha proseguito nelle universitï¿œ e ha conosciuto 
l'ingegneria del software, e chi come me che ha iniziato a lavorare 
sull'M24 usando clipper e gwbasic.. (e oggi continuo a studiare, mai 
sazio di imparare) e ognuno si porta ancora dietro i propri mostri 
sacri, come ad esempio il tabï¿œ del GOTO e di altri costrutti di cui si 
ï¿œ giï¿œ parlato in abbondanza.
Thread come questi servirebbero piï¿œ spesso, per sciacquare la mente dai 
retaggi e rinfrescarla con concetti sempre stimolanti :)
Ciao
-- 
Morde

 > commodore 64 (o 16 o 128) o il vic 20... non avevano queste strutture?
xche il basic di quei computer era microsoft.... :-))
A.

 citandolo come un'artefatto della programmazione strutturata, ecc.. :-O
Al "goto" va data l'importanza che ha, se ne ha e ne va riconosciuta la
pericolosit�. Non c'� dubbio che il "goto" � da evitare, se si vuol
scrivere codice pulito, con salti condizionali ben controllati; ugualmente
non c'� dubbio che il goto serva e sia indispensabile (come gi� detto, non
� solo questione di comodit�) in altri casi.
Demonizzare a prescindere � sempre sbagliato.


Il problema non e' il goto... Il problema e' il buon senso di chi
scrive il codice.
A.

 scrive il codice.
Si certo, ma restando in tema col mio post, immagina com'erano quei 
tempi: uno degli insegnati ad esempio era laureato in matematica, e non 
arrivava in ufficio con il notebook, lo apriva, e ci insegnava a 
programmare... si leggevano testi dove c'erano termini quali 
Direttorio, fincato, ecc..
In quel contesto, io non avevo neanche idea che fare il programmatore 
mi avrebbe un giorno portato a scrivere in UML e a "parlare con un 
servizio distribuito su internet".... erano altri tempi, e neanche il 
buon senso avrebbe impedito ai professori di darti un 4 se usavi un 
goto per uscire da 3 cicli annidati..
:-D
-- 
Morde

 servizio distribuito su internet"....
Ogni giorno mi chiedo "..ma xche non ho fatto l'idraulico??"...
A.

 Come posso aggirare l'ostacolo?
for j:= Utensili_file.Count - 1 downto 0 do
begin
    if (... espressione ...) then  utensili_file.Delete(j);
end;
Ciao, Dario

 ha scritto nel messaggio 
news:4b4c420c$1...@news.x-privat.org...

Proprio come hai detto prima. Apparteniamo allo stesso periodo allora :)
 

 Ciao, Dario
Grazie Dario,
e grazie per il tempo che mi dedicate. Purtroppo io non ci riesco ad
arrivare: Utensili_file.Count cambia il proprio valore all'interno del
ciclo perchè viene cancellato un elemento di Utensili_file. Il ciclo
for dovrebbe ricalcolare il valore di Utensili_file.Count ogni volta
che il ciclo ha inizio anzichè farlo una sola volta, la prima volta.
Non ho provato a fare il ciclo al contrario ma mi sfugge il motivo per
cui, in quel modo, dovrebbe funzionare. Anzi, mi aspetterei che non
funzionasse proprio.
In un post precedente all'interno di questo thread ho aggiunto che mi
era sfuggito che cancellando un elemento della lista all'interno del
ciclo avrei "saltato" un elemento della lista, quindi ho trasformato
il mio ciclo while da così ...
  j := i + 1;
  while j < Utensili_file.Count do
    begin
      if (... espressione ...) then
      begin
      ...
        utensili_file.Delete(j);
      ...
      end;
      j := j+1;
    end;
... a così ...
  j := i + 1;
  while j < Utensili_file.Count do
    begin
      if (... espressione ...) then
      begin
      ...
        utensili_file.Delete(j);
      ...
      end
      ELSE
      j := j+1;
    end;
In pratica se cancella un elemento della lista non incrementa l'indice.

 funzionasse proprio.
Lista con 5 elementi:
[0,1],[1,2],[2,3],[3,4],[4,5]
Il primo valore è l'indice, il secondo è il contenuto.
Il valore di lista.count = 5.
L'indice della lista inizia a contare i suoi elementi partendo da 0,
parto a testare dall'ultimo elemento, il quinto, che ha come indice 4, 
il mio ciclo dovrà partire da 4 per arrivare a 0
For x := lista.count-1 downto 0 do  (4 to 0)
   if Condizione then
     lista.delete(x)
cancella l'ultimo elemento della mia lista, che adesso è:
[0,1],[1,2],[2,3],[3,4]
al prossimo giro di for x assume valore 3, che è appunto l'ultimo 
elemento valido della mia lista.
Con x=3 la mia condizione dice di non cancellare dunque la mia lista non 
si è modificata, ma il valore di x si è decrementato adesso x assume 
valore 2, in questa condizione bisogna cancellare, dunque 
lista.delete(x), la lista adesso vale:
[0,1],[1,2],[2,4] e cosi' per tutto il ciclo for sino a x=0
Spero di essere stato chiaro.
^_Goblin_^
-- 
Ibis et redibis non morieris in bello
http://goblinland.myminicity.com/

 funzionasse proprio.
Spiegami perche'.
A.

funzionasse proprio.
la spiegazione � banale: quando cancelli il 1' elemento da una lista di n, 
hai come conseguenza che il 2' elemento diventa 1', e l'n-mo diventa l'n-mo 
meno 1. Quindi un ciclo "i" da 1 a n, che cancelli l' "i-mo" elemento 
fallisce per ovvii motivi. Potresti fargli cancellare sempre il primo, a 
prescindere dall'indice del ciclo, oppure farlo ciclare all'indietro, 
dall'ultimo elemento al primo, cancellando l'i-esimo.
Sandra 

Goblin, M.Sandra e Alberto Salvati, grazie, adesso mi è chiaro che
cancellando elementi mentre si procede a ritroso non ci sono
controindicazioni. Non ci ero arrivato subito.
Alberto Salvati, mi sono sbagliato: ero bollito. Di fatto il valore di
Utensili_File.Count cambia puntualmente: l'errore List Index Out Of
Bounds era dovuto all'utilizzo di un altro indice, i.

 funzionasse proprio.
Dunque, cerco di spiegarmi. In un ciclo come il tuo
for j:=0 to Utensili_file.Count - 1 do begin
  if (... espressione ...) then
    utensili_file.Delete(j);
end;
la variabile j aumenta sempre di 1 ad ogni passaggio mentre
Utensili_file.Count
come giustamente dici tu viene di volta in volta aggiornato in base
alle eliminazioni
eventuali degli elementi. Il problema nasce proprio qui perchè j (se
vi sono eliminazioi)
arriverà ad un punto che sarà superiore a Count con il conseguente
crash;
Con il ciclo al contrario invece il problema non nascerà mai in quanto
j sarà
sempre minore o uguale al numero di elementi di Utensili_file.
Provare per credere! :-)
Ciao, Dario

 Ciao, Dario
Ciao Dario,
sicuramente non hai letto il mio post precedente. A furia di darci
l'ho capito anche io! :)
Grazie ancora
Francesco