Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Costrutto do-while con variabile flag

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

4
voti

[21] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteTardoFreak » 15 ott 2015, 1:18

Le variabili di flag, che costituiscono il risultato di un'operazione logica, si usano solo se servono, anche perché di solito è sufficiente scrivere la condizione di ingresso e permanenza (nel ciclo while) o di sola permanenza (nel ciclo do-while) direttamente senza usare flag.
La domanda è: quando servono?
Servono quando l'espressione logica deve venire utilizzata, per qualche motivo, anche all'interno del ciclo.
Per esempio:
Codice: Seleziona tutto
do
{
  flag = una_operazione_a_piacere();
  // ...
  if (flag) { // Fa qualcosa che può modificarmi il valore di flag }
} while(flag);


Un altro caso in cui si usano le varibili di flag è quando bisogna evitare il cortocircuito delle valutazioni delle espressioni logiche. Es:
Siano
Codice: Seleziona tutto
char a(void) { ... }
char b(void) {...}
char c(int n) {...}

Tre funzioni che ritornano un valore da interpretare come vero o falso.
E sia
Codice: Seleziona tutto
(a() && b() && c(4))

la condizione di permanenza in un ciclo do-while.
Se io uso un flag calcolando il risultato in questo modo
Codice: Seleziona tutto
flag = a();
flag = flag && b();
flag = flag && c(4);

Sono sicuro che, oltre ad aver calcolato il valore dell'espressione logica, le tre funzioni a,b,c sono state eseguite.
Mentre se scrivo
Codice: Seleziona tutto
do
{
  //..
} while (a() && b() && c(4))

Se la chiamata alla funzione "a" ritorna un valore di falso, il compilatore (o l'ottimizzatore) evita di chiamare le altre due funzioni perché essendo un'operazione di and basta che il primo risultato, o comunque uno solo dei tre, sia falso che tutta l'espressione dia come risultato falso. Quindi è inutile chiamare le altre due funzioni.
Tradotto: non ho la sicurezza che tutte e tre le funzioni vengano comunque eseguite.

Come già detto giustamente in altri interventi prima di questo, la differenza fra il ciclo while ed il do-while è che nel while la condizione controlla sia l'ingresso che la permanenza nel ciclo, mentre ne do-while controlla la sola permanenza nel ciclo.
Il risultato è che il do-while viene almeno eseguito una volta (manca la condizione di ingresso) mentre il while può anche non essere eseguito mai (dovuto alla condizione che controlla anche l'ingresso).
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

3
voti

[22] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteSjuanez » 15 ott 2015, 8:47

Agli usi descritti dall'ottimo Foto UtenteTardoFreak, per le flag, si può aggiungere quello della leggibilità del codice.

Metti che la condizione non sia una robetta di due o tre aspetti, ma stai cercando una ragazza per il weekend. Allora vorresti che tutte le seguenti condizioni si avverassero (valore TRUE):

:arrow: capelli biondi
:arrow: single
:arrow: senza figli
:arrow: senza papà di campagna che alle 23 la cerca fucile in spalla
:arrow: simpatica
:arrow: dal buon profumo
:arrow: che non mangia o beve troppo altrimenti ti rovina
:arrow: che ha la macchina perché quella dei tuoi l'hai fracassata
:arrow: che insomma, apprezza la vita
:arrow: non si fa scrupoli a lasciare l'amica sola
:arrow: continua tu...

Ecco, tutte queste condizioni, messe all'interno di un ciclo while, ma anche all'interno di qualsiasi struttura di controllo del flusso, renderebbero il codice illeggibile o almeno parecchio incasinato, così si una una variabile riassuntiva dal nome esplicito che nel controllo sostituisce tutti questi requisiti, ad esempio: quella_giusta. Tale variabile contiene il risultato del confronto di quegli aspetti visti prima.

Questa operazione, aggiunge almeno una riga di codice, ma migliora molto la leggibilità e il debugging (ricerca di errori). A volte non viene fatta subito, ma ad una rilettura del codice, per migliorarlo (refactoring)

Su un PC si fa di continuo e non rappresenta alcun problema, mentre se si può fare o è consigliato sui microcontrollori (visto che parliamo di C), meglio che te lo dicano altri.

Buon coding!
O_/ O_/ O_/
Più so e più mi accorgo di non sapere.

Qualsiasi cosa abbia scritto, tieni presente che sono ancora al mio primo rocchetto di stagno.
Avatar utente
Foto UtenteSjuanez
11,3k 6 8 13
G.Master EY
G.Master EY
 
Messaggi: 3479
Iscritto il: 18 mar 2015, 13:48

2
voti

[23] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteTardoFreak » 15 ott 2015, 12:51

Su questo aspetto non mi trovi d'accordo anche se, in un passato recente, la pensavo anch'io così.
Ultimamente ho capito (e me lo hanno anche fatto capire a forza) alcune cose.

Il software va progettato.
Ricordo che all'istituto tecnico ci davano dei compiti di progettazione (es: polarizzazione di uno stadio amplificatore) che svolgevamo sulla carta. Il progetto doveva essere fatto, calcolato e scritto senza provarlo fisicamente. E tutto doveva essere giusto.
La stessa cosa deve essere fatta con il software. La progettazione stile "scrivo una linea e faccio subito il debug" è sbagliata, soprattutto se si tratta di studio. Come con i circuiti i programmi devono essere progettati, calcolati e devono funzionare sulla carta con sicurezza 100%.

Si usa una variabile solo se questa serve.
Anche questo è un principio che oggi ritengo più che mai valido e si spiega da se. Come mettere un componente inutile in un circuito è un errore, anche inserire una variabile (o una linea di codice) inutile in un programma lo è. Fare una variabile riassuntiva per poi metterla al posto di una condizione complessa si fa solo se quella variabile serve anche altrove.
Se una persona ha problemi di lettura, affronta e risolve questi problemi, che poi problemi non sono, mi spiego meglio:
In Java è abbastanza comune passare degli oggetti ai metodi (le funzioni in C). E' ovvio, meno ovvio è quando, al posto di un oggetto, si scrive direttamente una classe anonima.
La classe anonima si usa quando, si quell'oggetto, ne serve solo una istanza e solo come parametro per quel preciso metodo.
In pratica, al posto di una "int n" si scrive una dichiarazione completa di classe (che può essere anche lunga e complessa) al posto di quel parametro. Perché si fa questo? Perché si dice implicitamente che di quella classe serve solo quel singolo oggetto e solo per quel metodo. Se io vedo la dichiarazione al di fuori della lista dei parametri penso subito che, di quella classe, ne verranno utilizzate più istanze, e quindi penso sbagliato. E chi ha scritto questo ha commesso un errore perché ha introdotto un qualcosa che non serve.
Ora sappiamo bene che una condizione composta, per quanto lunga sia, no è mai complessa come la dichiarazioni di un'intera classe, e quindi il problema non esiste.

Come pure i controlli inutili (non serve ma non fa male a nessuno) sono degli errori perché, se scrivo un controllo, questo deve avere una ragione d'essere. Non si mettono righe a kaxxum in un programma.

Confesso che inizialmente questi concetti mi sembravano astrusi e senza senso. Mi sbagliavo perché, e lo vedo sul lavoro, oggi lavoro meglio, più velocemente e, soprattutto, con più precisione e tranquillità di aver scritto un codice che funziona non perché l'ho provato, ma funzione perché funziona e basta.
E non torno indietro.

Prendendo spunto dal tuo esempio, non vedo dove stia il problema nello scrivere
Codice: Seleziona tutto
do
{
  // altre linee
  r = cercaRagazza();
} while(!(isBionda(r) && isSingle(r) && !hasFigli(r) &&
        !hasPapy(r) && isSimpatica(r) && hasGoodScent(r) &&
        isModerata(r) && hasCar(r) && amaLaVita(r) &&
        isSenzaScrupoli(r) && varieEdEventuali(r)));
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

0
voti

[24] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteIlGuru » 15 ott 2015, 13:22

Se ad esempio nelle funzioni isbionda( . ), is_shaved( . ), ... , varieEdEventuali( . ) setto dei flag, quando eseguo
isbionda(r) && ... && varieEdEventuali(r) se varieEdEventuali(r) mi ritorna 0, tutte le altre non vengono eseguite e non mi ritrovo il flag f_bionda settato nemmeno se la tipa è platinata.
Inoltra a volte, specialmente nei microcontrollori dove lo spazio di stack è limitato a pochi byte, non è possibile eseguite molte chiamate annidate ad esempio
Codice: Seleziona tutto
a = f0( f1( f2() ) );

e tocca sacrificare lo spazio per una variabile scrivendo
Codice: Seleziona tutto
a = f2();
a = f1( a );
a = f0( a );
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
5.482 2 10 13
G.Master EY
G.Master EY
 
Messaggi: 1924
Iscritto il: 31 lug 2015, 23:32

1
voti

[25] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteSjuanez » 15 ott 2015, 13:51

Si, Foto UtenteTardoFreak, io, te e altri già discutemmo di questo contrappasso tra efficienza e costo/lavoro.

Capisco benissimo il tuo punto di vista, ho voluto solo far presente questo ulteriore utilizzo molto diffuso ed incoraggiato in molti corsi e libri di primaria importanza.
(es. http://martinfowler.com/books/refactoring.html)

Credo che il fatto di lavorare in grandi team, renda più vantaggioso puntare sulla leggibilità e interpretazione immediata del codice, invece di progettare il capello a priori (che richiede tanto tempo). La cosa dovrebbe aver a che fare con i principi del famoso metodo Agile.

E' solo una mia opinione, che mi interesso a queste cose più o meno per hobby, ma ho la possibilità di incontrare tantissimi "pro" del settore.

Io personalmente mi trovo benissimo così, sopratutto quando mi serve leggere codice scritto dagli altri nelle varie repo di GitHub. Sono felice che utilizzino una scrittura più "spiegata", anche in barba a quel po di efficienza di calcolo persa.

:D Quindi, sia chiaro anche e soprattutto all'OP, non volevo in nessun modo andare a "sovrascrivere" la tua validissima spiegazione, solo scrivere una piccola nota in calce su quella che mi pare un'usanza diffusa.

O_/ O_/ O_/
Più so e più mi accorgo di non sapere.

Qualsiasi cosa abbia scritto, tieni presente che sono ancora al mio primo rocchetto di stagno.
Avatar utente
Foto UtenteSjuanez
11,3k 6 8 13
G.Master EY
G.Master EY
 
Messaggi: 3479
Iscritto il: 18 mar 2015, 13:48

2
voti

[26] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteTardoFreak » 15 ott 2015, 14:57

IlGuru ha scritto:...Inoltra a volte, specialmente nei microcontrollori dove lo spazio di stack è limitato a pochi byte, non è possibile eseguite molte chiamate annidate ad esempio
Codice: Seleziona tutto
a = f0( f1( f2() ) );

e tocca sacrificare lo spazio per una variabile scrivendo
Codice: Seleziona tutto
a = f2();
a = f1( a );
a = f0( a );

Questo non è completamente vero perché i compilatori odierni raramente utilizzano lo stack per il passaggio di argomenti. Nel caso specifico che hai riportato non viene proprio utilizzato, a meno di utilizzare un micro che ha solo l'accumulatore ad 8bit, nessun registro interno e che la variabile "a" e gli argomenti delle varie funzioni siano, ad esempio, di 4byte. Allora è ovvio che si usi lo stack ma quali micro odierni si ritrovano in questa situazione (niente registri interni e parola corta)?

Sappi Foto UtenteSjuanez che il refactoring lo faccio anch'io, o almeno l'ho fatto parecchie volte in C riorganizzando i moduli in modo che fossero bene incapsulati e contenessero funzioni coerenti fra di loro ed efficienti. Soprattutto l'incapsulamento per non avere una marea di defines, variabili e funzioni uitli solo nello scope del modulo ma assolutamente "incasinanti" se visibili dall'esterno.
Di sicuro non per riscrivere una funzione tipo
Codice: Seleziona tutto
void writeString(char *s)
{
  while(*s) writeChar(*s++);
}

In una così
Codice: Seleziona tutto
void writeString(char *s)
{
  char ch;
  ch = *s;
  while(ch != 0) {
    writeChar(ch);
    s++;
  }
}

Solo per fare un semplice esempio, eh! :-)

Con i linguaggi ad oggetti il discorso è un po' diverso ma, anche in questi casi, sono altre le cose a cui prestare attenzione. Ad esempio l'ereditarietà in Java che, se non usata con la testa, può portare problemi, che non derivano da una facile leggibilità ma dalla mancanza di una progettazione specifica della classe.
Una classe che deve essere ereditata deve essere progettata per tale scopo. Bisogna porre grande attenzione all'override dei metodi e bisogna documentarla bene soprattutto negli effetti che gli eventuali override produrrebbero, altrimenti sorgono dei problemi monumentali.
E questo è solo un esempio ma, purtroppo ce ne sono tanti altri molto più importanti che la facilità di lettura del sorgente.

PLast but no least una parola sui miei articoli. I sorgenti sono scritti male, qualcuno molto male. Lo dico oggi perché lo so e per amore di sincerità. :ok:
E mentirei se dicessi che più volte ho sentito l'impulso si rimuoverli o di aggiornarli in modo opportuno. Ma quel che è stato è stato e fa comunque parte della mia storia personale.
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

1
voti

[27] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteSjuanez » 15 ott 2015, 15:03

Come già ti dissi anche nell'altra discussione, sono pienamente consapevole e d'accordo sul vantaggio di documentare il tutto, magari con UML o quello che uno preferisce (soprattutto i diagrammi di classe). Con la programmazione ad oggetti è quantomai necessario questo procedimento.

Ripeto, dicevo solo che quella della variabile "riassuntiva" per facilitare la lettura del codice è una cosa molto diffusa e io l'apprezzo. Però pure fumare mi piace, è diffuso e non per forza una buona abitudine. :D

L'importante è fare queste cose responsabilmente :mrgreen:
Più so e più mi accorgo di non sapere.

Qualsiasi cosa abbia scritto, tieni presente che sono ancora al mio primo rocchetto di stagno.
Avatar utente
Foto UtenteSjuanez
11,3k 6 8 13
G.Master EY
G.Master EY
 
Messaggi: 3479
Iscritto il: 18 mar 2015, 13:48

1
voti

[28] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteSjuanez » 15 ott 2015, 15:04

TardoFreak ha scritto:PLast but no least una parola sui miei articoli. I sorgenti sono scritti male, qualcuno molto male. Lo dico oggi perché lo so e per amore di sincerità. :ok:
E mentirei se dicessi che più volte ho sentito l'impulso si rimuoverli o di aggiornarli in modo opportuno. Ma quel che è stato è stato e fa comunque parte della mia storia personale.


E io ti auguro di trovare imbarazzanti tutti i tuoi sorgenti ogni 2-3 anni, perché significa che sei migliorato un sacco. A me capita e ne sono felice. O_/ O_/ O_/
Più so e più mi accorgo di non sapere.

Qualsiasi cosa abbia scritto, tieni presente che sono ancora al mio primo rocchetto di stagno.
Avatar utente
Foto UtenteSjuanez
11,3k 6 8 13
G.Master EY
G.Master EY
 
Messaggi: 3479
Iscritto il: 18 mar 2015, 13:48

1
voti

[29] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteWALTERmwp » 15 ott 2015, 17:56

ot piccolino ...
[ot ]
boiler ha scritto:(...) e gli regalo mezza giornata di debugging. Con il do-while, non funziona. :twisted:
... se, dove ti trovi, anche solo una persona potrebbe sfiorarti la tastiera, anche solo dovesse esserci un gatto, anche solo si trattasse di gatto sedentario (prima o poi si muove anche lui), e comunque a maggior ragione ti dovesse capitare un collega "zuzzerellone" come Foto Utenteboiler, mai, riscrivo, mai, lasciare aperto l'ide, l'editor, anche fosse solo costituito da penna e bloc notes (potrebbe imitare la tua scrittura) ... pena ritrovarsi un codice dal comportamento più che inaspettato ...
[/ot ]
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8990
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

1
voti

[30] Re: Costrutto do-while con variabile flag

Messaggioda Foto UtenteTardoFreak » 15 ott 2015, 18:01

Sjuanez ha scritto:E io ti auguro di trovare imbarazzanti tutti i tuoi sorgenti ogni 2-3 anni, perché significa che sei migliorato un sacco. A me capita e ne sono felice. O_/ O_/ O_/

Ti ringrazio per l'augurio :-) anche se oggi le cose sono cambiate.
Fino a due anni fa era quello che mi auguravo anch'io :ok: , oggi non lo è più perché ho deciso di smettere di fare il manovale della programmazione e studiare informatica come Dio comanda. ;-)
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

PrecedenteProssimo

Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 16 ospiti