Problema con i flag nel linguaggio c

FemtoGinny
Hello world!! Sono proprio alle prime armi con il c, e dei flag ho capito solo che si impostano al valore 1 che sta a significare vero, o che comunque un evento si e verificato, o si resettano al valore 0 e quindi falso. Tuttavia, per esempio nel semplice bubblesort descritto nei primi 3 min del video https://m.youtube.com/watch?v=-WV_mq76RGo, se qualcuno avesse la bontà di dargli un occhiata rapida, non capisco molte cose inerenti ai flag @.@ per esempio che significato ha scrivere all inizio del while flag_completed=1? E perché alla fine delle iterazioni c'è invece flag_completed=0? Come fa il programma a sapere che l'algoritmo e terminato? Potreste spiegarmi passo passo? Grazie infiniterrime volte ^^

Risposte
Summerwind78
Ciao


non ti preoccupare se le prime volte che hai a che fare con il c non capisci molte cose. E' assolutamente normale :D

venendo alla tua domanda:
i flag non sono altro che variabili a cui si assegna un valore definito che ci dice se una certa operazione è stata eseguita, oppure se una particolare evento è avvenuto o cose simili

in questo caso tu hai un ciclo gestito da un "while".

while(condizione)
{
istruzione 1
istruzione 2
...
}



Il while esegue ciò che è contenuto all'interno della sua parentesi graffa fino a che la condizione iniziale è vera.

nel tuo caso specifico il while esegue il suo contenuto fino a che "flag_completed" è uguale a zero

lo vedi in quanto hai che la condizione è
while(!flag_completed)


infatti il codice mette a zero flag_completed subito prima del while per fare in modo che il contenuto del while venga eseguito almeno una volta.

All'interno del while, flag_completed viene impostato = 1 presumendo che alla fine delle vari istruzioni all'interno del while si possa quindi uscire.
Se però una serie di condizioni si verificano, ovvero ciò che accade dentro il "for" allora flag_completed viene di nuovo impostato a zero e il while viene eseguito nuovamente.
Se invece le condizioni presenti nel "for" non si verificano, allora flag_completed rimane = 1 e il ciclo while finisce

Questo in senso più generico, nel tuo caso specifico vedo che si tratta di un bubbleSort quindi il tuo codice funziona nel seguente modo:

1) metto flag_completed = 0 prima del while così sono entro nel ciclo la prima volta.
2) quando sono nel while imposto flag_completed = 1 così se nel for supponendo che non avrò alcuna coppia di elementi dell'array che scambierò di posizione nell'array stesso.
3) usando un ciclo "for" prendo a 2 a 2 tutti gli elementi dell'array e vedo se devo scambiarli di posizione
4) se ho scambiato di posizione ad almeno una coppia di elementi, allora imposto flag_completed = 0 in modo da non uscire da while e torno al punto 2)
5) se invece non è stato necessario scambiare di posizione alcuna coppia di elementi significa che il mio array è già ordinato quindi il mio lavoro è finito, avendo flag_completed = 1, non ripeto più il contenuto del while e il mio bubble sort è terminato

Spero di esserti stato di aiuto

Se qualcosa non ti è chiaro chiedi pure

Saluti

Saluti
successivo non ho scambiato la posizione di almeno due elementi dell'array vuol dire che non ci sono più elementi da scambiare e il mio lavoro e terminato quindi esco dal while., vado a vedere se devo scambiare di posizione almeno un elemento del mio array. Se ne ho scambiato almeno

Sherlock.h
Ciao, provo ad aiutarti, ma se puoi aspetta qualcuno di più esperto.
A mio avviso quel pezzo di codice non è molto intuitivo. Può essere reso in modo più intuitivo sostituendo la condizione del while con la seguente:
while (flag_completed==0)

Fatta questa modifica provo ad esporre nel modo più chiaro che mi riesce quanto da te richiesto.

Il ciclo while, come avrai oramai intuito, si ripete finché la variabile flag_completed si presenta all'istruzione di controllo con il valore 0.

La variabile flag_compared serve a far capire al programma se l'array è (stato) ordinato, oppure no. Vale 1 nel caso in cui l'array sia (stato) ordinato, 0 in caso contrario. È evidente che il programma deve continuare ad eseguire il contenuto del ciclo while finché il vettore non è ordinato, quindi finché flag_compared risulta essere uguale a 0.

All'inizio di ogni ciclo si sceglie di impostare quella variabile ad 1, in modo da permettere la terminazione del ciclo.
È ovviamente necessaria quella riga di codice perché, nel caso in cui non cambiasse il valore di flag_completed durante l'esecuzione del while, otterresti un ciclo infinito, in quanto flag_compared è inizializzata a 0.

Poi si entra nella parte più "operativa" della funzione, nella quale c'è lo swap tra i valori dell'array nel caso in cui si presenti la condizione arr>arr[i+1]. Come vedi questa condizione è inserita all'interno di un ciclo for, grazie al quale vengono presi in considerazione tutte le coppie di elementi adiacenti possibili. Se almeno una delle coppie arr, arr[i+1] soddisfa la condizione arr>arr[i+1], beh, allora mi sembra ovvio che l'array non è ordinato, di conseguenza flag_compared deve valere 0, e quindi le si dà il valore 0.

Quando il ciclo si ripete, come già detto, si dovrà dare al ciclo la possibilità di terminare, quindi si reimposta flag_compered a 1.
Nel caso in cui il vettore sia ormai ordinato, non verrà soddisfatta la condizione arr>arr[i+1], non ci sarà nessuno swap, ma soprattutto il valore di flag_compared resterà 1.
Nel momento in cui si ripresenterà l'istruzione di controllo del ciclo, dato che flag_compared non è più uguale a 0, bensì a 1, il ciclo terminerà.

Ti sconsiglio di studiare da video su YT l'informatica, e di affidarti a dei buoni manuali. Ciao :!:

Sherlock.h
SummerWind, non avevo visto la tua risposta, ti chiedo scusa.

Summerwind78
@Sherlock.h: figurati, mi sa che l'abbiamo scritta più o meno nello stesso momento :D

FemtoGinny
Ragazzi *0* vi ringrazio infinite volte, siete stati chiarissimi e avete risolto il mio dubbio... Tranne che per una piccola insicurezza: Se flag_completed all'inizio è stato dichiarato uguale a 0, e se l'operatore ! ritorna l'opposto dell'elemento che lo segue, allora !flag_completed non dovrebbe significare che flag_completed è diverso da 0, e quindi 1? :oops:

axpgn
Se flag_completed è uguale a zero allora la sua negazione sarà diversa da zero; isn't it? :wink:

FemtoGinny
Esatto! Ma se Il while esegue ciò che è contenuto all'interno della sua parentesi graffa fino a che la condizione iniziale è vera, e la condizione iniziale è !flag_completed che è la negazione di flag_completed=0, allora in teoria il ciclo while sarà eseguito fino a quando il contenuto della sua parentesi sarà diverso da 0! È questo che non capisco @.@
Comprendo invece la versione di Sherlock (che mi sembra opposta) nella quale abbiamo while (flag_completed==0) perché in questo caso il while viene eseguito finche flag_completed permane vera, e quindi finche il suo valore resta 0.
Scusate il casino xD

Summerwind78
In realtà non è una definizione opposta quella di Sherlock.

Il fatto è che il il valore zero all'interno di una variabile è considerato per definizione come un valore "falso"

quindi scrivere


while(cond)
{
istruzione
}


se cond è pari a zero, il ciclo while termina.

Invece se cond assume qualsiasi valore diverso da zero, il ciclo while continua

Mi rendo conto che sia più difficile da utilizzare all'inizio questo metodo, ma è abbastanza comune

FemtoGinny
Aaaah! Ora ha tutto un senso ^^ mi mancava questa nozione per capire! Grazie grazie e grazie :smt023

axpgn
@Summerwind
Che tu sappia questo fatto è una convenzione che dipende dal linguaggio usato o è una consuetudine che si tramanda dalla notte dei tempi (anche gli usi e costumi sono fonti del diritto ... :-D )

Cordialmente, Alex

Summerwind78
A quanto ne so, è una caratteristica del linguaggio C ANSI

ma potrei sbagliarmi

apatriarca
È comune a molti linguaggi in realtà, non solo al linguaggio C. Ha senso se visto dal punto di vista di un programmatore di basso livello. La mancanza di un tipo booleano in C è la principale motivazione dietro alla scelta di introdurre questo tipo di logica. In effetti, sono praticamente solo i linguaggi con tipi molto più "rigidi" a non averla.

axpgn
In effetti è un metodo che ho visto usare in diversi linguaggi (solo che non è molto intuitivo per chi inizia ... :-) )
E peraltro non mi ricordo di aver mai visto in C cose tipo ".T." o ".F." (ma questo è più un problema di memoria ... :-D)

apatriarca
In C moderno ci sono _True e _False (o true e false se si include stdbool.h). Ma è una aggiunta recente e il tipo booleano corrispondente (_Bool o bool) non si usa molto. In C++ invece è più comune l'uso di bool, true e false.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.