Interrompere ciclo for

(deleted)

ciao

Break

ciao
pippo72

Io posso dirti come si esce da un ciclo qualsiasi (for, while, do while, ...), si usa l'istruzione break ... come fare però per richiamarla devi vedere tu.

Nel ciclo for dovrai controllare la pressione di un dato tasto e, se la rilevi, chimi la break.

Guglielmo

P.S.: pippo72 mi ha anticipato :smiley:

(deleted)

gpb01:
P.S.: pippo72 mi ha anticipato :smiley:

Infatti ho scritto un post molto breve per batterti sul tempo :smiley: :smiley: :smiley:

ciao
pippo72

stando alla teoria, non si dovrebbe uscire da un ciclo for (li si usa quando il numero di iterazioni è noto) ma piuttosto sostituirli con dei while (li si usa quando il numero di iterazioni non è inizialmente noto) ed invalidare la condizione di ciclo

ciao :slight_smile:

automatic_jack:
stando alla teoria, non si dovrebbe uscire da un ciclo for

Ma assolutamente no, ci sono mille motivi per cui è desiderabile uscire da una for, o da altre condizioni di ciclo, non a caso esiste la break e la continue, la prima interrompe immediatamente il ciclo, la seconda riporta immediatamente all'inizio del ciclo.
Esempio pratico, devo acquisire n campioni e uso la for, però se uno dei campioni vale 0 devo invalidare il ciclo e buttare i dati, ecco che la break risolve il problema, verifico il valore acquisito, se diverso da 0 continuo il ciclo altrimenti lo termino immediatamente senza sprecare tempo macchina per finire un ciclo inutile.

astrobeed:
Ma assolutamente no, ci sono mille motivi per cui è desiderabile uscire da una for, o da altre condizioni di ciclo, non a caso esiste la break e la continue, la prima interrompe immediatamente il ciclo, la seconda riporta immediatamente all'inizio del ciclo.
Esempio pratico, devo acquisire n campioni e uso la for, però se uno dei campioni vale 0 devo invalidare il ciclo e buttare i dati, ecco che la break risolve il problema, verifico il valore acquisito, se diverso da 0 continuo il ciclo altrimenti lo termino immediatamente senza sprecare tempo macchina per finire un ciclo inutile.

stando al tuo esempio il miglior ciclo è il do...while: faccio una lettura e continuo a leggere fino a che non raggiungo n campioni o uno dei campioni è 0

quel che intendevo col mio post è che il for dovrebbe ciclare un numero finito e predeterminato di volte, se il numero di cicli è indeterminato (perchè dipende da diverse condizioni) allora è più opportuno usare un ciclo while/do...while

ciao :slight_smile:

automatic_jack:
quel che intendevo col mio post è che il for dovrebbe ciclare un numero finito e predeterminato di volte,

Continui a non capire, o non voler capire, la for() su usa quando serve fare un numero di cicli predeterminato, però questo non vuol dire che non capiterà mai un motivo per il quale è necessario terminarla.
Il mio esempio era volutamente banale per chiarire la cosa, nel mondo reale non è raro avere delle condizioni, p.e. un flag o un allarme, per le quali è indispensabile terminare la for e passare a fare altre cose.
Tra parentesi, a livello di codice assembly, la for di solito è più veloce della while, richiede meno cicli macchina per essere elaborata, questo a parità di condizione di verifica, però dipende anche dal compilatore e dal livello di ottimizzazione.
Di sicuro se devi eseguire un ciclo per un numero fisso di iterazione è meglio usare la for() piuttosto che la while anche per motivi di leggibilità del codice, se trovo una for so subito che è una iterazione finita, una while può anche non finire mai, cosa che può causare grossi problemi se non si prevedono sistemi di emergenza per terminare un ciclo infinito non voluto.

astrobeed:
.... Tra parentesi, a livello di codice assembly, la for di solito è più veloce della while, richiede meno cicli macchina per essere elaborata ....

Infatti ... e non per nulla, nel "core" di Arduino, il main() richiama in continuazione la loop() mettendola dentro una:

for( ; ; ) { .... }

e NON in una:

while(true) { .... }

Guglielmo

astrobeed:
Continui a non capire, o non voler capire, la for() su usa quando serve fare un numero di cicli predeterminato, però questo non vuol dire che non capiterà mai un motivo per il quale è necessario terminarla.
Il mio esempio era volutamente banale per chiarire la cosa, nel mondo reale non è raro avere delle condizioni, p.e. un flag o un allarme, per le quali è indispensabile terminare la for e passare a fare altre cose.
Tra parentesi, a livello di codice assembly, la for di solito è più veloce della while, richiede meno cicli macchina per essere elaborata, questo a parità di condizione di verifica, però dipende anche dal compilatore e dal livello di ottimizzazione.
Di sicuro se devi eseguire un ciclo per un numero fisso di iterazione è meglio usare la for() piuttosto che la while anche per motivi di leggibilità del codice, se trovo una for so subito che è una iterazione finita, una while può anche non finire mai, cosa che può causare grossi problemi se non si prevedono sistemi di emergenza per terminare un ciclo infinito non voluto.

la questione è abbastanza accademica...dal punto di vista del c standard i cicli while e do...while sono iterativi, il ciclo for è controllato: i primi iterano in funzione di una condizione, i ciclo for itera in funzione della condizione (centrale) e sotto il controllo delle condizioni laterali (sinistra prima della prima iterazione e destra dopo ogni successiva iterazione)

ora le due tipologie dovrebbero uscire se la condizione di ciclo diviene falsa. tale conizione nel while/do...while è libera laddove nel for è controllata dalla condizione di sinistra/destra

l'uscita da un ciclo for con un break viola il princio del controllo

MA, non è che non si possa...meglio sarebbe usare un while

nella pratica sta molto allo sviluppatore: qualcuno usa sempre i for, altri solo i while, altri - pochi - si basano sui principi esposti sopra, qualcuno usa i for nei giorni dispari ed i while nei pari (ecco perchè i for sono di più)

gpb01:
Infatti ... e non per nulla, nel "core" di Arduino, il main() richiama in continuazione la loop() mettendola dentro una:

for( ; ; ) { .... }

e NON in una:

while(true) { .... }

Guglielmo

non ho ancora avuto modo di guardarne i sorgenti...colpa del poco tempo

nel gcc, però, il primo è riconosciuto (ed il ;; è sostituito dalla costante EVER sicchè si legga for EVER) laddove il secondo no

nei p-languages, invece, è prodotto il medesimo bytecode

automatic_jack:
nel gcc, però, il primo è riconosciuto (ed il ;; è sostituito dalla costante EVER sicchè si legga for EVER) laddove il secondo no

Prima di tutto Arduino si programma in C/C++, pertanto non ha alcun senso fare il paragone con altri linguaggi, for(;:wink: non esiste nessuna costante EVER in C, semplicemente è una sintassi prevista dalle regole del C e il compilatore si comporta di conseguenza.
While(true), while(1), anche loro sono sintassi valide in C/C++ dato che la while, o do while, altro non fa che usare il risultato logico della condizione, se questo è fisso a 1 (true) il ciclo è eterno fino a che non viene terminato internamente con la break.

Vorrei fare una considerazione, nel linguaggio C-C++ il for() e il while() sono abbastanza intercambiabili, si potrebbe "anche se poco bello" usare un for() al posto del while() visto che si basa su condizioni.
Mentre in linguaggio come Python o il potente Basic, il for esegue SOLO un numero determinato di iterazioni.

while(k=='c'){

    

}

o

for(;k=='c';){ //MOLTO BRUTTO ma funziona :)

      
}

aggiungo solo, per correttezza, che al momento (gcc (Debian 5.4.0-6) 5.4.0 20160609), for( ; ; ) e while(1) producono lo stesso codice macchina (x86_64-linux-gnu) nello specifico:

for( ; ; )

for.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
int main() {
   0: 55                   push   %rbp
   1: 48 89 e5             mov    %rsp,%rbp
 for(;;) {}
   4: eb fe                 jmp    4 <main+0x4>

while(1)

while.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
int main() {
   0: 55                   push   %rbp
   1: 48 89 e5             mov    %rsp,%rbp
 while(1) {}
   4: eb fe                 jmp    4 <main+0x4>

lo stesso accade con avr-gcc (avr-gcc (GCC) 4.9.2)

automatic_jack:
aggiungo solo, per correttezza, che al momento (gcc (Debian 5.4.0-6) 5.4.0 20160609), for( ; ; ) e while(1) producono lo stesso codice macchina (x86_64-linux-gnu) nello specifico:

E con questo cosa vuoi dimostare ?
Come ho specificato for( ; ; ) e while(1) sono due casi particolari che il compilatore affronta a modo suo, come lo fa dipende dal compilatore, o meglio da chi l'ha scritto, e dal livello di ottimizzazione.
Va da se che i due casi possono essere gestiti allo stesso identico modo se esplicitamente previste nel codice del compilatore, li riconosce e può generare identico codice visto che fanno la stessa identica cosa.
In tutti i casi questo discorso è andato su un binario che non ha nulla a che vedere con la domanda iniziale, ovvero come uscire forzatamente da un ciclo for, la risposta è usare la "break", tutto il resto è solo retorica.

E con questo cosa vuoi dimostare ?

Ho come l'impressione che non abbia intenzione di dimostrare nulla, si è solo tolto un dubbio circa il lavoro svolto dal compilatore.

Io d'istinto tendo ad usare il while anche quando mi serve un contatore, poi però mi interrogo se sia il caso di usare un for o altro, poi se il codice funziona preferisco il for per i cicli non interrotti da break e il while per il resto, il do while manco lo caco di striscio. :smiley:

Ciao.

Seguendo le direttive di Atmel bisogna usare for( ; ; ) per i cicli infiniti e do{}while(); ,quando possibile, per facilitare le ottimizzazioni del compilatore.
Oltre a questo l'uso di for o while varia in base al codice è non vi è una regola scritta se non uno stile per poter generare codice elegante.

il resto, come direbbe @astro, è solo fuffa.