Untitled Document
mIRC in Italiano - Script - Forum - Imposta come Home Page - Aggiungi ai Preferiti - Home - Chat
Utenti connessi: - Visitatori oggi: - Visitatori totali: - Pagine viste oggi:


NewsLetter


localprogrammazione
-
----
-
----
-
----
-
----

-
----
-
-
-
-
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----
-
----

----
C: IF e i Cicli

Benvenuti alla seconda lezione della guida al C di SukkoPera! La prima lezione è sempre la più tragica! Spero siate anche riusciti a svolgere l'esercizio che vi ho lasciato. Eccovi comunque una possibile soluzione, che mi ha inviato il caro Azz0:

 


--- 02_sol1.c ------------------------------------------------------------------------------------

#include <stdio.h>

int main (void) {

int ore, min, min_tot;


printf ("Inserisci l'ora corrente (hh:mm): ");

scanf ("%d:%d", &ore, &min);


min_tot = ore * 60 + min;

printf ("Sono trascorsi %d minuti dalla mezzanotte.\n", min_tot);


return (0);

}

--------------------------------------------------------------------------------------------------


La "difficoltà" di questo esercizio risiedeva nell'usare il formato giusto per scanf (e nel ricordarsi le '&'). Spero che questo concetto vi sia (ormai) chiaro!

Può darsi che qualcuno abbia avuto l'idea di calcolare i SECONDI trascorsi dalla mezzanotte, anziché i minuti. In tal caso sarà probabilmente impazzito nel tentativo di capire perché a volte ottiene un risultato sbagliato. Be', è perfettamente normale, e vi sarà chiaro fra qualche lezione, non temete ;).

LEZIONE 2


Come promesso, in questa lezione parleremo di if e di cicli.


Una caratteristica FONDAMENTALE dei linguaggi di programmazione è quella che ci permette di fare sì che un programma si comporti in modo diverso a seconda di certe condizioni. Senza questa caratteristica non potremmo fare niente (provare per credere)! Consideriamo un compito banale, come far introdurre da tastiera un numero intero e scrivere sullo schermo se tale numero è positivo o negativo. Una possibile soluzione è la seguente:


--- 02_sgn.c -------------------------------------------------------------------------------------

#include <stdio.h>

int main (void) {

int n;


printf ("Introduci un numero intero: ");

scanf ("%d", &n);


if (n > 0) {

printf ("Il numero che hai inserito è POSITIVO.\n");

} else if (n < 0) {

printf ("Il numero che hai inserito è NEGATIVO.\n");

} else {

printf ("Il numero che hai inserito è ZERO.\n");

}

return (0);

}

--------------------------------------------------------------------------------------------------


Fino alla riga di scanf il programma dovrebbe risultarvi comprensibile (se non è così, rivedetevi la lezione precedente!). Quel che segue è il famigerato if: esso ci permette di valutare una condizione, che nella fattispecie può essere una qualsiasi espressione, e, se essa è vera (ossia, nel nostro caso, se il numero è maggiore di 0), viene eseguito tutto quel che è compreso tra le {} successive. Se essa è falsa, si passa alla valutazione delle condizioni indicate successivamente come else if (dato che non è maggiore di 0, il nostro numero è forse minore di 0?) e, appena se ne trova una vera, essa viene eseguita. Infine, se nessuna è vera, si esegue quello indicato dal ramo else (se il nostro numero non è né maggiore né minore di 0, allora è proprio 0! Inutile fare altri controlli). Nessun ramo, a parte il primo è necessario, quindi sono perfettamente legali cose come le seguenti:


if (a == 0) {

printf ("a vale 0.\n");

}


che stampa un messaggio solo se a è uguale a 0, altrimenti prosegue semplicemente con l'istruzione successiva;

if (b == 0) {

printf ("b vale 0.\n");

} else {

printf ("b non vale 0.\n");

}


che stampa un messaggio diverso a seconda che b sia uguale a 0 o meno. Non c'è nessun ramo else if in questo caso.


Il discorso mi pare abbastanza intuitivo, quindi passiamo subito ai particolari: vi capiterà spesso di dover valutare più di una condizione alla volta. Ad esempio, vogliamo sapere se un certo anno è bisestile o meno. Ricordiamo che un anno è bisestile se è divisibile per 4 ma non per 100, oppure per 400. Quindi 1996 è bisestile perchè 1996 % 4 == 0 e 1996 % 100 != 0 (ricordate l'operatore '%' dalla prima lezione, vero?). 2000 è bisestile perché 2000 % 400 == 0. 1900 invece no, perché 1900 % 4 == 0, ma anche 1900 % 100 == 0. Passiamo ad una realizzazione software; intuitivamente potreste pensare di fare (supponendo che nella variabile "anno" ci sia un anno valido, inserito ad esempio mediante scanf):


if (anno % 400 == 0) {

printf ("L'anno è bisestile.\n");

} else if (anno % 4 == 0) {

if (anno % 100 == 0) {

printf ("L'anno non è bisestile.\n");

} else {

printf ("L'anno è bisestile.\n");

}

} else {

printf ("L'anno non è bisestile.\n");

}


Questo è talmente intricato che non so nemmeno io se funzioni! Fortunatamente, qualsiasi linguaggio vi permette di raggruppare più condizioni in un unico if. Per farlo vi sono 2 operatori: il primo è di AND logico, e fa sì che l'if sia eseguito solo se TUTTE le condizioni specificate sono vere. Esso si indica con "&&". L'altro operatore è di OR logico, e fa sì che l'if sia eseguito se ALMENO una delle condizioni è vera. Esso si indica con "||" (ALT+124 casomai mancasse sulla vostra tastiera). Ovviamente potete raggruppare più condizioni in una sola con un misto di and ed or, usando le parentesi per maggior chiarezza. Quindi l'intricato codice soprastante si può ridurre a:


if ((anno % 400 == 0) || (anno % 4 == 0 && anno % 100 != 0)) {

printf ("L'anno è bisestile.\n");
} else {
printf ("L'anno non è bisestile.\n");

}


Sicuramente è un po' più semplice a scriversi e a capirsi ;).

Un'altra considerazione che è necessario fare riguarda gli operatori che potete utilizzare negli if: per testare l'uguaglianza di due variabili dovete usare l'operatore "==" (che sono DUE uguali, e NON uno, sia ben chiaro!!); per testare la disuguaglianza di due variabili dovete usare l'operatore "!=" (che potete chiamare "diverso"); infine, il "maggiore o uguale" ed il "minore o uguale" si indicano rispettivamente con ">=" e "<=". Per ora non vi serve sapere altro.

Veniamo al secondo grande argomento di questa lezione: i cicli. Supponiamo che vogliate scrivere 5 volte su schermo "SukkoPera è il mio idolo." (ihihih!). Nessuno vi vieta di fare:


printf ("SukkoPera è il mio idolo.\n");

printf ("SukkoPera è il mio idolo.\n");

printf ("SukkoPera è il mio idolo.\n");

printf ("SukkoPera è il mio idolo.\n");

printf ("SukkoPera è il mio idolo.\n");


se non il buon senso. Immaginate di volerlo scrivere 50 volte. E poi 100. Insomma, sarete d'accordo con me che è una soluzione assolutamente impraticabile ;). I cicli servono appunto a darvi una mano in compiti del genere, ossia quando volete ripetere un certo numero di volte determinate operazioni. In questo caso possiamo usare un semplice ciclo FOR, che in C si realizza come segue:


for (i = 0; i < 5; i = i + 1) {
printf ("SukkoPera è il mio idolo.\n");

}


Questo farà esattamente la stessa cosa del codice di prima (chiaramente dovete avere dichiarato "int i;"), ma in un modo più compatto e più facilmente modificabile: se ora volete stampare la scritta 100 volte, vi basta cambiare "i < 5" in "i < 100", semplice, no?


Analizziamo più da vicino la struttura del for: notiamo che tra le () sono riconoscibili 3 parti, separate da ';': la prima è la parte di INIZIALIZZAZIONE e contiene istruzioni che verranno eseguite SOLO LA PRIMA VOLTA che si entra nel ciclo. Qualcuno penserà: "Allora tanto vale metterle prima del for.", ed in effetti ha ragione, solo che specificarle dentro al for rende più chiaro ciò su cui il ciclo lavora, anche se questo non è per nulla vincolante.

La seconda parte, invece, contiene le CONDIZIONI DI USCITA dal ciclo: il ciclo sarà ripetuto fino a quando la condizione che esprimete qua sarà vera. Quando sarà falsa il ciclo terminerà ed il programma proseguirà con l'istruzione successiva al for. È importante capire che questa condizione verrà testata soltanto ALLA FINE del gruppo di istruzioni da ripetere, non in mezzo ad esse. Faremo un esempio chiarificatore tra poco.

La terza parte, infine, contiene le istruzioni di INCREMENTO: esse vengono eseguite ogni volta che si arriva al termine del gruppo di istruzioni da ripetere, dopodiché vengono testate le condizioni di uscita.

Solitamente tutte e 3 le parti lavorano sulle stesse variabili. Se non è così sarebbe meglio utilizzare un ciclo WHILE, che spiegheremo tra poco.

Dopo le () vi è un insieme di istruzioni racchiuse tra {} come negli if, che è il blocco di istruzioni che verrà ripetuto.

Vediamo ora un esempio un po' più complesso di for:


for (i = 1; i <= 10; i = i + 1) {
for (j = 1; j <= 10; j = j + 1) {
printf ("%d ", i * j);

}

printf ("\n");

}


Questi sono detti "cicli for NIDIFICATI", perché uno è interamente compreso dentro all'altro. Questo programmino (sempre a patto che abbiate dichiarato "int i, j;") stamperà una simpatica tabellina pitagorica (si chiama così, no?). Seguiamo il programma passo per passo: all'inizio entriamo nel primo for, e i viene inizializzata a 1. Dopo di che, entriamo anche nel secondo for, e j viene inizializzata a sua volta a 1. Quindi viene eseguita la prima istruzione del ciclo, ossia la prima printf, che stamperà il valore di i * j, ossia 1 * 1, e quindi 1. Troviamo poi la } di chiusura del for più interno, quindi viene eseguita la sua istruzione di incremento, ossia j = j + 1, e quindi j passa a 2. Successivamente viene testata la condizione di uscita del ciclo più interno: j <= 10. Valendo j 2, la condizione è ovviamente verificata, quindi il ciclo sarà ripetuto, e verrà di nuovo eseguita la prima printf. È importante a questo punto capire che niente ha modificato il valore di i, e quindi essa varrà ancora 1, in quanto non siamo ancora giunti alla fine del primo for (che in questo caso è rappresentata dalla seconda printf), e quindi non è ancora stata eseguita la sua operazione di incremento. Il valore stampato dalla printf sarà ovviamente 1 * 2, quindi 2, dopo di che tutto andrà esattamente come abbiamo appena spiegato, stampando su schermo i numeri fino al 10 (che rappresentano la tabellina dell'1): a quel punto, i varrà ancora 1, e j varrà appunto 10. Subito dopo la printf verrà eseguita l'istruzione di incremento del for più interno, e j arriverà a valere 11. Quindi sarà testata la condizione di uscita: j <= 10. Ovviamente 11 non è <= 10, e dunque il ciclo for più interno sarà finito, e si passerà ad eseguire quello che segue, in questo caso la seconda printf, che non farà altro che fare andare a capo il cursore. Ora siamo arrivati alla fine del ciclo for esterno, quindi sarà eseguita la sua istruzione di incremento, che farà sì che i passi a valere 2, mentre per ora j continuerà a valere 11, ossia il valore che ha provocato l'uscita dal for interno. Verrà poi testata la condizione di uscita del for esterno: 2 è <= 10, quindi esso verrà eseguito nuovamente. Ora siamo di nuovo al punto di partenza del for interno: j viene inizializzata ad 1 e man mano saranno stampati i valori 2 * 1, 2 * 2, 2 * 3... fino a 2 * 10, valori che rappresentano la tabellina del 2. Quindi sarà nuovamente concluso il ciclo for interno, il cursore sarà mandato a capo, sarà eseguita l'istruzione di incremento del for esterno e quindi sarà stampata la tabellina del 3, e così via, fino a quando sarà stampata la tabellina del 10: a quel punto i passerà a valere 11, la condizione che ci mantiene dentro al for esterno non sarà più verificata, e quindi si passerà ad eseguire quel che segue, che in questo caso si suppone sia un "return (0);" che conclude il programma.


Spero che questo discorso vi sia chiaro. Può darsi che dobbiate rileggere un paio di volte quanto scritto sopra, ma alla fine vi renderete conto che non è troppo complesso. Se proprio non capite, provate a compilare ed eseguire il seguente programma:


for (i = 1; i <= 10; i = i + 1) {

for (j = 1; j <= 10; j = j + 1) {

printf ("i = %d, j = %d, i * j = %d.\n", i, j, i * j);


getchar ();

}

printf ("Fine ciclo FOR interno.\n\n");
getchar ();

}


printf ("Fine ciclo FOR esterno.\n\n");


Esso è praticamente identico al precedente, solo che eseguirà un passo alla volta visualizzando i valori man mano assunti dalle variabili, aspettando che premiate invio (a causa di getchar ();) prima di passare al successivo.


Un'ulteriore precisazione: potete utilizzare più variabili nelle varie parti di un for, ad esempio:


for (i = 0, j = 10; i < 10 && j > 0; i = i + 1, j = j - 1) {

}


Da questo dovrebbe essere chiaro che dovete usare la virgola ',' per separare più elementi della stessa parte, e che la condizione di uscita dal ciclo è tale quale una condizione di un if, e quindi anche in essa potete usare gli operatori logici come "&&" e "||".


Un altro tipo di ciclo è il ciclo WHILE. A dire il vero, in C si può considerare un while un semplice ciclo for che manca sia delle condizioni di inizializzazione, sia delle istruzioni di incremento. In pratica il ciclo while si preoccupa solo di ripetere un certo insieme di operazioni finché una condizione è vera, senza eseguire contestualmente inizializzazioni o incrementi. Esempio:


while (x != 5) {

printf ("Inserisci 5 per uscire: ");
scanf ("%d", &x);

}


Come dicevamo, il while è molto simile ad un for "mutilato", in effetti la riga del while potrebbe equivalentemente essere scritta "for (; x != 5;). Non esiste differenza (i compilatori dovrebbero produrre codice assembler identico in entrambi i casi), se non una maggior chiarezza.

Comunque, lo spezzone di codice soprastante chiede di inserire un numero da tastiera, e finché non inseriamo '5', la domanda viene ripetuta, in quando la condizione è verificata. Da notare è che se x vale 5 quando arriviamo al while, esso non sarà mai eseguito, in quanto la condizione viene testata ANCHE LA PRIMA VOLTA che si entra nel ciclo. Esiste tuttavia una forma leggermente diversa del ciclo while:


do {

printf ("Inserisci 5 per uscire: ");
scanf ("%d", &x);

} while (x != 5);


Questo è un ciclo DO... WHILE, in tutto e per tutto identico al while, con l'unica differenza che la condizione viene testata solo DOPO che le istruzioni sono state eseguite, e quindi esse verranno eseguite ALMENO una volta.


Presentiamo un esempio pratico dell'uso di questo tipo di ciclo, in questo caso per effettuare il controllo di un dato inserito e farlo reinserire se scorretto:


do {

printf ("Inserisci una data nel formato gg/mm/aaaa: ");
scanf ("%d/%d/%d", &giorno, &mese, &anno);

} while ((giorno > 0 && giorno <= 31) && (mese > 0 && mese <= 12));


Finché non viene inserita una data valida, la domanda viene riproposta.

Questo è quanto è necessario sapere sull'if e sui cicli. Per questa lezione lascio anche una piccola appendice, che tratta 2 argomenti che possiamo definire "avanzati": essi non sono fondamentali a questo punto del corso, quindi siete liberi di ignorarli. Tuttavia se avete capito tutto alla perfezione e volete altra carne al fuoco, sapete dove trovarla ;)

APPENDICE:


Nell'uso degli if, del ciclo for e del ciclo while (non nel do... while), il C permette di omettere le {} che delimitano i vari blocchi di istruzioni, qualora si tratti di un'istruzione sola. Ad esempio, l'if del primo programma si potrebbe tranquillamente scrivere:


if (n > 0)
printf ("Il numero che hai inserito è POSITIVO.\n");
else if (n < 0)
printf ("Il numero che hai inserito è NEGATIVO.\n");
else
printf ("Il numero che hai inserito è ZERO.\n");


dato che l'istruzione da eseguire nei vari casi è sempre una sola. Tuttavia, quando scriviamo cose del genere, può capitare di aggiungere altre istruzioni successivamente, quindi è necessario ricordarsi di aggiungere le {} dove appropriato, oppure di usarle sempre. Abbondare non fa mai male, anzi, spesso rende più chiaro il codice alla lettura e, a volte, può anche rendere più veloce la compilazione. Questo vale anche per le () nella valutazione delle espressioni logiche e aritmetiche, Notate anche che parentesi superflue NON influiranno negativamente sulle performance del programma, in quanto eliminate automaticamente in fase di compilazione, quindi non fatevi scrupoli ad usarle ;).


Un'ultima parola su come le espressioni vengono valutate: in C, il valore logico VERO corrispondere ad un QUALSIASI numero DIVERSO DA 0. Quindi, ovviamente, il valore logico FALSO corrisponde SOLO ALLO 0. Siccome in un if può comparire un'espressione qualsiasi, se il suo risultato sarà diverso da 0, l'if verrà eseguito, altrimenti si passerà a valutare gli else if e poi l'else. Ecco quindi che cose senza senso come le seguenti sono perfettamente legali:


if (5 + 4 - 9 / 3) {

/* Quello che mettete qua verrà SEMPRE eseguito, dato che il risultato dell'espressione è 6, e quindi corrisponde a VERO */

}

if (8 + 7 - 15) {

/* Quello che mettete qua non verrà MAI eseguito, dato che il risultato dell'espressione è 0, e quindi corrisponde a

FALSO */

}


Spero che questo discorso vi sia chiaro. Tra l'altro, ne ho approfittato per introdurre i COMMENTI. In C, quando compare la sequenza di caratteri "/*", tutto quel che segue è considerato un commento, ed ignorato dal compilatore, fino a quando non compare la sequenza "*/". Un commento può comparire in un qualsiasi punto in cui può comparire uno spazio. Imparate fin da subito a commentare i vostri programmi, vi tornerà molto utile quando rimetterete mano a del codice scritto tempo prima. Credetemi, i commenti sono fondamentali, e non ne scriverete mai abbastanza! Certi compilatori supportano anche la sintassi per i commenti del C++, ossia "//", che però definisce un commento su una sola riga: in questo caso non serve una sequenza di caratteri per chiudere il commento, basta andare a capo. Vi sconsiglio comunque di utilizzarli: stiamo programmando in C, non in C++!

ESERCIZIO


Anche questa volta vi lascio con un esercizio che servirà a farvi utilizzare i concetti esposti in questa lezione. Ovviamente troverete una possibile soluzione nella prossima lezione, nella quale, a proposito, parleremo di vettori.


Scrivere un programma che permetta di inserire due numeri da tastiera. Il programma dovrà stabilire (e stampare su schermo con un messaggio appropriato) quale di essi è il maggiore (gestire anche il caso di uguaglianza) e, successivamente, per quest'ultimo, calcolare la somma di tutti i numeri interi, partendo da 1 ed arrivando fino ad esso.


Esempio:

Inseriti 4 e 7, il programma avvertirà che il numero maggiore è 7 e che la somma richiesta è 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28.


Vi lancio anche una piccola sfida: dato il ciclo:


for (i = 0; i < 100; i = i + 1) {

/* ... */

}


scriverne una versione EQUIVALENTE al 100% usando il ciclo while. Divertitevi ;).


### FINE LEZIONE 2 - Versione 1.01 (23/01/2003) ###




  Ultime dal forum
  Ultimi File Inseriti
Diablo III (14624)
Fancazzista Scr... (18764)
Sensuality scri... (7622)
Grand Theft Aut... (5154)
Stealth Script ... (8382)
-SagittarioScri... (18835)
Paradise Script (13753)
Trivia Game 200... (11882)
Ircap Script 8.... (5191)
RawScript 2.0 (8481)


 

 


Cerca nel sito

Le ultime news:



Sondaggio
Cosa vorresti di nuovo?

Risultati | Archivi

Statistiche Download
Database:
283 Files
241 Mb
Scaricati:
2659868 Files
Totale: 5615348Mb

Upload
Hai realizzato uno Script? Una addon? Una tcl? Un articolo? Qualsiasi cosa? Mandacelo ora! Utilizza il form upload per inviarci il tuo materiale e se lo riteniamo idoneo lo vedrai pubblicato nel portale!
[ Upload ]

Chat
Inserisci il tuo nick:



| Contattaci | Pubblicità | Staff |
Il presente materiale è Copyright TuttoIRC.it 2005. Leggi il Disclaimer