Newsgroup: it.comp.lang.c
Titolo: Non riesco a visualizzare il risultato!

Ciao a tutti!
Ora che posso finalmente usare il compilatore, ho un primo piccolo
problemuccio :-). Ho "creato" il programma più stupido del mondo, che
calcola l'area di un rettangolo. Quando lo eseguo, inserisco il valore
della base, schiaccio invio, inserisco il valore dell'altezza, schaccio di
nuovo invio... e poi misteriosamente la finestra di DOS si chiude. Eppure
il programma non finisce lì!
Forse esegue tutto troppo velocemente e termina prima che l'occhio possa
vedere il risultato? Come si può fare per "bloccare" il programma dopo la
restituzione del risultato, magari schiacciando invio per uscire?
Qui sotto vi copio-incollo il codice.
Grazie in ogni caso!
Rocky3
/* Calcolo area rettangolo*/
#include <stdio.h> //E' necessario per poter usare la printf, così come
tutte le altre funzioni di input/output
int base, altezza, area;
main()
{
      printf("Ecco un buon programma per un banale calcolo: l'area di un
rettangolo\n\n");
      //Vado a capo due volte per inserire una riga vuota dopo questo
"titolo"
 
      printf("Inserire (qualunque sia l'unità di misura) la lunghezza della
base: ");
      scanf("%d", &base);
      //Il simbolo % indica che il carattere seguente definisce il formato
di acquisizione dell'input utente, mentre d indica che tale input è un
numero intero decimale
      printf("Inserire ora la lunghezza dell'altezza: ");
      scanf("%d", &altezza);
 
      area = base*altezza;
      //Ho assegnato il valore corretto alla variabile area
 
      printf("Ecco quello che il programma ha capito e fatto:\n");
      printf("Base: %d\n", base);
      printf("Altezza: %d\n", altezza);
      printf("Area: %d\n", area);
}
-- 
"Il sapere e la ragione parlano, l'ignoranza ed il torto urlano".
Arturo Graf / Indro Montanelli / Anonimo

}

 }
Visto che se agli inizi, ti indico alcune regole che in genere sono usate
per i commenti.
I commenti non devono essere troppo lunghi, cerca di dire quello che devi
con il minor numero possibile di parole, è più facile capire per chi legge
(anche per te stesso).
Esempio 1
- "Vado a capo due volte per inserire una riga vuota dopo questo "titolo"
- "Inserimento di una riga vuota dopo il titolo"
Esempio 2
- "E' necessario per poter usare la printf, così come tutte le altre
funzioni di input/output"
- "Per usare printf e altre funzioni di I/O"
Esempio 3
- Ho assegnato il valore corretto alla variabile area
- Calcolo dell'area
In genere il commento viene messo sulla stessa riga di una istruzione (sulla
destra, dopo l'istruzione) oppure sulla riga precedente l'istruzione (non su
quella dopo).
Quindi:
    // Calcolo area
    area = base*altezza;
oppure
    area = base*altezza;     // Calcolo area
Evita  i commenti banali. Non bisogna abusarne. Vanno messi solo quando
danno un effettivo aiuto alla comprensione di quello che c'è scritto. Ora
sei all'inizio, quindi ok, ma poi commenti come "E' necessario per poter
usare la printf, così come tutte le altre funzioni di input/output" puoi
fare a meno di metterlo.
Inoltre visto che sei all'inizio, è bene che ti abitui fin da subito a
scrivere il software in C seguendo delle convenzioni di scrittura.
Dai un'occhiata qui.
http://www.itis.mn.it/linux/stile/index.htm
E' solo un esempio. Se cerchi, troverai altri esempi.
Alcune sono delle regole praticamente universalmente accettate da tutti,
altre vanno un po' a gusto personale. L'importante è che quando si è scelto
una convenzione, si segua sempre quella. Se poi vai a lavorare in un posto
dove vengono seguite delle convenzioni, ti devi adattare a quelle che sono
già usate.

 implicita.
Questo significa che il risultato del main() dovrà necessariamente essere
un intero?
Ho aggiunto
char stop;
nella dichiarazione delle variabili e poi
stop = getchar();
alla fine, dopo l'ultima istruzione. Ho dato un'occhiata al manuale e non
capisco cosa c'è che non va. Resta comunque il fatto che rispetto a prima
non è cambiato nulla!
Grazie comunque!
Rocky3


 
http://www.itis.mn.it/linux/stile/index.htm
Ok, ti ringrazio!
Rocky3


 originale come idea, e volevo iniziare a capirci qualcosa.
Si, sei all'inizio, quindi fai pure le cose che ritieni utile, almeno in
questi primi tempi.
Siccome sei all'inizio ti ho dato delle indicazioni, così le conosci già,
poi comincia ad applicarle se e quando lo ritieni utile.
Se nel futuro dovrai scrivere SW per professione, queste indicazioni saranno
molto importanti, se invece ti fermerai ad un ambito di solo studio, lo sono
già meno.
Buona continuazione!!!
Marco

non è cambiato nulla!
Strano.  E' possibile che si sollevi un errore prima dell'ultima
istruzione e quindi al getchar() non si arrivi mai.  Esegui il tuo
programma da linea di comando.

 valore restituito da una funzione.
Aggiungo anche che,  evitando di memorizzare il valore restituito da 
getchar,  si evita l'  errore, normale per i principianti,  di 
assegnarlo ad una variabile char invece che int.
Giorgio

 non è cambiato nulla!
Perdona la domanda banale.  Ma dopo aver modificato il tuo file .c,  lo 
hai anche ricompilato ?
Giorgio

 programma da linea di comando.
Cioč con il debug? Nel qual caso leggi il post che ho scritto il 13/10...
ho dei problemi anche lě :-(


 hai anche ricompilato ?
Sě, l'ho rifatto adesso per scrupolo e non funziona!


 }
nb: se non vuoi impazzire per stupidi effetti collaterali, non ti 
conviene mai usare scanf(), neanche nei semplici programmini di prova. 
Usa la coppia fgets + sscanf.
ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 
Ti rimane uno '\n' nel buffer di input perche' la scanf() non se lo 
'mangia'. La getchar() trova come carattere di input quello... ed esce 
subito dal programma.
Usa invece qualcosa del genere:
while((stop = getchar()) != 'q' && stop != 'Q')
         ; /* attende q+INVIO */
...o ancora meglio, non usare la semplice scanf (gia' meglio la coppia 
fgets + sscanf).
ps. la variabile 'stop' andrebbe dichiarata "int", come ti hanno gia' 
consigliato, per evitare possibili errori su cast impliciti. Anche se in 
questo caso specifico non ti cambia molto: non hai da controllare l'EOF 
(int -1) che si puo' confondere con il carattere ASCII esteso 255 (char -1).


          ; /* attende q+INVIO */
Così è un po' più "leggibile".
do
    stop = getchar();
while ((stop != 'q')  &&  (stop != 'Q'));

 sscanf(bf, "%d", &base);
Per fare le cose bene, bisognerebbe per sicurezza controllare che
effettivamente sscanf abbia eseguito la conversione.
Se non si dà in input un numero intero, sscanf non trova nessun numero
intero in "bf", quindi non fa nessuna conversione e "base" non è definito.
Questo errore andrebbe gestito.

Marco ha scritto:

Certo! :-)


Marco ha scritto:

...in questo caso nulla da eccepire, ma attento che il do...while() e' 
un costrutto potenzialmente molto pericoloso. Per me e' come se non 
esistesse (in qualunque linguaggio di programmazione).
Ciao


 esistesse (in qualunque linguaggio di programmazione).
Mi dai delle motivazioni? Grazie
In alternativa se proprio vuoi usare il while e avere maggiore leggibilità
(forse con un piccolo spreco di memoria programma):
stop = getchar();
while ((stop != 'q')  &&  (stop != 'Q'))
      stop = getchar();

 Mi dai delle motivazioni? Grazie
...semplicemente perche', con la do...while, prima fai delle azioni e 
solo dopo ne controlli le condizioni per le quali queste debbano venire 
eseguite.



do {  leggi_da_input } while (input_diverso_da..);
in un caso cosi' il do-while è ottimo!
ciao 

 
Ma lo scopo del do { ... } while( ... )  non e` proprio questo?
Anche il while ( .. ) { ... } puo' essere pericoloso allora, visto che 
fa un test prima di eseguire le azioni.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

 eseguite.
Si, è proprio la differenza tra "do...while" e "while". Ma sono stati
pensati proprio per questo. Non lo vedo un problema.
Ci sono situazioni dove necessariamente l'azione deve essere eseguita almeno
una volta (come nel nostro caso, non posso dire se è stato premuto il tasto
Q se prima non eseguo l'azione di leggere se ci sono caratteri nell'input -
getchar()).
Ci sono situazioni invece dove l'azione può essere eseguita anche zero volte
se la condizione non è soddisfatta fin da subito.
Nel primo caso è più indicato usare il do...while, nel secondo il while, se
non altro per la leggibilità del codice.
Infatti è subito chiaro che:
- con il do...while si ha nell'ordine ("azione" - "verifica") - ("azione" -
"verifica") - ... (almeno 1 azione viene eseguita)
- con il while si ha nell'ordine ("verifica" - "azione") - ("verifica" -
"azione")- .... (possono essere eseguite 0 azioni)
Se vediamo il nostro caso ad esempio, anche nel caso del "while" prima fai
l'azione (il getchar lo fai prima, è "nascosto" nella condizione) e poi il
controllo.
Sono scritte in modo diverso, ma fanno la stessa cosa. Nel nostro caso
quindi le 2 cose sono equivalenti e forse il compilatore unito
all'ottimizzatore può tradurre le 2 cose addirittura nello stesso modo.
Quindi secondo me è meglio usare il do...while in questo caso, si comprende
meglio cosa fa il software. Non vedo controindicazioni.
Marco

 un costrutto potenzialmente molto pericoloso.
ciao


 fa un test prima di eseguire le azioni.
Certo. Se sca22i le condizioni di test sicuramente si' :)
ciao


 se la condizione non è soddisfatta fin da subito.
"quasi sempre" e' cosi'. E il do...while e' "quasi sempre" la scelta 
sbagliata per iniziare un ciclo che, a priori, pensi debba essere 
eseguito almeno una sola volta. Se sbagli la previsione su un ciclo 
*complesso* (magari rimettendoci successivamente le mani) poi ti tocca: 
o rabricciare con rischio di bug (ecco perche' pericoloso), o 
ricostruirlo tutto sotto forma di while() o for()... e in questo caso 
smoccoli parecchio, perche' di norma cambiano anche le varie condizioni 
dentro il ciclo.
Ma e' solo la mia esperienza... tu usa pure il costrutto che ti pare 
meglio :)
Ciao


 Certo. Se sca22i le condizioni di test sicuramente si' :)
Allora tutti gli statement sono pericolosi ;-) (se non sono corretti)
Ciao


 while ((stop != 'q')  &&  (stop != 'Q'));
Mi sono perso un po' nelle vostre discussioni :-), nel senso che non sono
ancora in grado di seguirle a pieno. Vi ringrazio, perň, per tutti i vostri
interventi... e fortunatamente con questo "escamotage" sono riuscito ad
ottenere quello che volevo. Ora il programma non termina finché non premo
q.
Grazie ancora!


 q.
o non premi il tasto 'Q' (oltre che 'q')
Per le nostre discussioni non ti preoccupare, sono cose che arrivano un po'
dopo, ossia prima devi imparare le basi del linguaggio e ad usarlo nelle sue
varie modalità, poi quando hai un po' di esperienza e hai questa conoscenza
di base ti puoi chiedere se è meglio fare una cosa in un modo piuttosto che
in un altro.

 in un altro.
Aggiungo solo una cosa.
La cosa importante è che tu abbia capito perchè prima non funzionava e ora
funziona e cosa fanno le nuove istruzioni aggiunte.

 funziona e cosa fanno le nuove istruzioni aggiunte.
Giusta osservazione. Dunque:
- ora funziona perché viene eseguita la getchar() (il cui "compito"
tuttavia mi č ignoto) finché la variabile stop, per effetto della getchar()
stessa, non assume valore q o Q. A quel punto si esce dal ciclo e finisce
il programma;
- non so ancora perché prima non funzionava.


esistesse (in qualunque linguaggio di programmazione).
Anche per me.  E' uno dei motivi, ad esempio, per cui nella
programmazione Pascal/Delphi non uso *mai* repeat..until (equivalente
del do..while ma con condizione d'uscita anziché di permanenza nel
ciclo).

 ciclo).
...io proprio 'mai' usato -- e non mi e' neanche 'mai' servito :)


 ciao
Si ho letto cosa hai scritto
dicevo solo che la sua struttura (verifica le condizioni alla fine) ben si 
presta al caso
di sopra, (ossia prende un valore da input, finchè quel valore non è quello 
richiesto dal programma), anche se il classico while (..) non lo batte 
nessuno... :) 

...io proprio 'mai' usato -- e non mi e' neanche 'mai' servito :)
Come al 99% dei programmatori C/C++.
Spero che il do..while venga abolito nel prossimo standard... :-)


Tra non usare una caratteristica e sperare che venga abolita ce ne 
passa. Intanto sarebbe interessante capire la tua statistica del 99%  su 
che si basa.
Poi,  se ci pensi, tenendo conto del numero di programmatori C,  anche 
se fosse vero il tuo 99%,  l'  1%  di un grande numero non č  poco in 
termini assoluti.
Infine,  tutta l'  argomentazione č  poco convincente. TUTTI   i 
costrutti sono potenzialmente pericolosi se si sbaglia ad usarli (o se 
non li si sa usare). Vogliamo abolirli tutti ? Finanche il goto non č 
stato bandito dallo standard!
Il buon Dijkstra suggerě  l' abolizione del go to su una base un tantino 
piů  solida.
Giorgio

 - non so ancora perché prima non funzionava.
Prima non è che non funzionava.
Ti riporto cosa hai scritto nel primo post di questo thread:
"Forse esegue tutto troppo velocemente e termina prima che l'occhio possa
vedere il risultato? Come si può fare per "bloccare" il programma dopo la
restituzione del risultato, magari schiacciando invio per uscire?"
Ti eri già risposto da solo.
Prima il programma arrivato all'ultima printf terminava. Ora invece lo
"blocchi" fino a che non premi 'q' o 'Q'.
In realtà non è che lo blocchi nel vero senso della parola, il programma è
sempre in esecuzione (sta eseguendo il loop). Quando premi 'q' o 'Q' esce
dal loop e termina.
Marco

TUTTI i costrutti sono potenzialmente pericolosi se si sbaglia ad usarli
Esistono costrutti, per natura, più pericolosi di altri.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Spero che il do..while venga abolito nel prossimo standard... :-)
ROTFL


 Per chi non sa codificare ogni statement e` potenzialmente pericoloso.
Io questa cosa non l'ho letta cosi'.
(per favore, evitate flames)


 (per favore, evitate flames)
Mi associo alla richiesta.

 
Non mi interessa scatenare flames, ma in vent'anni che programmo trovo 
ridicolo che qualcuno affermi che il costrutto do { ... } while (...) 
sia pericoloso.
Poi qualcuno dovrebbe spiegare perche` e` pericoloso!  Ribadisco che se 
si scrive programmi senza sapere cosa si sta facendo *tutti* gli 
statement diventano pericolosi.
Ciao
Giovanni


 statement diventano pericolosi.
Anch'io sono del tuo partito per quel che riguarda il do...while.
Marco

 statement diventano pericolosi.
Io ho provato a spiegare la mia ragione (probabilmente non a sufficienza 
- e comunque senza tentare d'imporla)... eventualmente altri avranno le 
proprie di ragioni... altri saranno d'accordo con te... ecc...
Tu prendine atto, ragionaci o discutine pure (se ti va)... poi fregatene 
se ognuno magari rimane nella propria verita'. Pace!...
Credo che i ng servano anche a questo: cioe' a confrontarsi. Talvolta il 
confronto puo' arricchirci, altre volte rimane fine a se stesso, altre 
volte ancora puo' essere quasi deleterio oltre che infruttuoso. Dipende 
da noi.
ciao :)


Taci, idiota.


> ciclo).
specialmente se rivolte ad un principiante non lo aiutano in alcun modo.


 
Hai finito di gonfiarti?  Guarda che il tuo ego prima o poi scoppia.


 per iniziare un ciclo che debba essere eseguito almeno una sola volta.
Io mi chiedo, anche, "perche'" affermi che "quel ciclo" *debba* essere 
eseguito *almeno* una volta. Secondo me l'hai valutato male.
Cioe': se la getchar() come *primo* carattere incontra una 'q' ... cosa 
diamine c'entra a fare dentro il ciclo?
E questo per me vale: sia in questo ciclo:
while((stop = getchar()) != 'q' && stop != 'Q')
{	; // eventuali altre operazioni
}
...come anche in quest'altro (che avete giudicato equivalente):
do
  	stop = getchar();
	// eventuali altre operazioni (...ma probabilmente
	// tutte da evitare se in 'stop' c'e' gia' un car. 'q')
while ((stop != 'q')  &&  (stop != 'Q'));
Inoltre, non ti sembra una condizione anomala quella di trovarsi 
"all'interno" del ciclo se la getchar() ti ha gia' restituito una 'q'?
E qui mi ripeto: se il programma dovesse crescere e, anziche' attendere 
solo l'uscita, il ciclo dovesse gestire un menu' di scelte, come faresti 
con questa "do...while"? Metti un 'break' o una 'if' dopo la 
getchar()...? poi come diventa il ciclo?
(se poi mi dirai che dentro il ciclo d'esempio non ci sono altre 
istruzioni... beh, allora mi userai un caso "limite" per sostenere 
questa tua affermazione...)
Ciao


"Andrea Laforgia" <a.laf...@andrealaforgia.it.invalid> ha scritto nel
messaggio news:vecdj29q351k392d4...@4ax.com...

Non avrebbe alcun senso eliminare il do {} while.
Esso è comunque di una qualche utilità.
Permette di esprimere nel modo "migliore" in assoluto
il raggruppamento di istruzioni senza avere l'overhead
di una chiamata di funzione mantenendo la stessa eleganza:
#include <stdio.h>
#define LIKE_A_FUN(X)               \
do {                                                 \
                a = 5 * (X) + 4;               \
                printf("%d\n",a);               \
} while (0)
int main(void)
{
        int a;
        LIKE_A_FUN(10);
        LIKE_A_FUN(12);
        return 0;
}
A parte questo "zucchero-sintattico"
il "do" permette di evitare, quando è il caso, un inutile test.
Se si dovesse proprio decidere quale costrutto iterativo
eliminare tra for, while e do certamente NON il "do"
che ha queste caratteristiche peculiari. Soprattutto il
risparmio del test!
E' vero che è meno usato anche perchè meno
idiomatico e forse meno facile da gestire
ma considera che le librerie run-time di diversi sistemi
embedded ne sono piene.
Spesso per motivi di efficienza.
--
Giorgio Silvestri
DSP/Embedded/Real Time OS   Software Engineer

 Spesso per motivi di efficienza.
(qui, pero', non ne sono sicuro...)


 di scatenare flames.
Non è vero Giovanni accetta l'opinione altrui, da quello che leggo.
Cmq se volete un costrutto potenzialmente pericoloso basta lo switch()
per sentito dire so che dichiarare una var dentro lo switch non funziona.. 
provate :) 

 (dalla faccina, penso sia stata una battuta)
Io invece penso che non sia stata una battuta.


Di cosa non sei sicuro ?
Abbiamo già detto che il do fa un test in meno ...


 non funziona.. provate :) 
seh, allora bandiamo anche gli if\else perche sono simili a uno switch ;)
comunque è vero, non si puo dichiarare una variabile dentro a uno switch, 
sia dentro che fuori dai "case". ma basta inserire tutto in un blocco {} 
e via che hai il workaround. personalmente, a meno di casi banali, uso 
sempre mettere i case dentro a un blocco...

 Abbiamo già detto che il do fa un test in meno ...
...ah scusa: prima non avevo sentito... :)
==
Comunque, ok. Qui mi hai convinto:
1) trick x costruire macro
2) particolari casi di ottimizzazione per evitare 1 (una) condizione di 
test in un ciclo.
3) ... altri esempi un po' piu' "pret-a-porter"? :)
Ciao :)


 Spesso per motivi di efficienza.
*Quale* efficienza ?


 appunto!
Certo che si può:
if (some_test)
  LIKE_A_FUN(10);
oppure:
if (some_test)
  LIKE_A_FUN(10)  /* senza il ; */
else
  print("stampa\n");
Una volta che ti sei imbarcato nell'obbrobriosa tecnica di usare una macro
come fosse una funzione, non ti scandalizzerai mica di saltare un punto e
virgola.


 (pace per il doppio ';' in fondo nella macro poi espansa) :)
I vantaggi di usare il costrutto 'do { ... } while(0)' nella 
dichiarazione di una macro e` chiaramente visibile proprio nell'esempio 
mostrato.
1) l'uso di { ... } definisce gia` un blocco e in certi costrutti 
complessi puo` generare problemi di blocchi nestati. do { } while(0) e` 
invece un solo statement.
2) non causa problemi con il doppio ';'. Anche se molti compilatori sono 
permissivi se incontrano '}' seguita da ';' in certe situazioni e` un 
errore. Per esempio:
	if ( a > 0 ) 	LIKE_A_FUN(a);
	else 		LIKE_A_FUN(a + 1);
per come hai riscritto la macro non e` compilabile ma lo sarebbe usando 
il do {} while(0).  Naturalmente puoi scrivere il codice senza mettere 
il ';' ma pensa se la macro e` in un header file e non direttamente 
visibile al programmatore.  Se il programmatore non vede direttamente il 
codice della macro diventa poi un problema di mantenubilita` e di 
usabilita`.
3) nella tua versione sei costretto a dichiarare la variabile 'a' (che 
sembra essere solo una variabile temporanea) all'inizio di main().  La 
macro non puo` essere usata in un'altra funzione.  Inoltre chi usa la 
macro deve sapere che il nome della variabile per poterla dichiarare. 
Se 'a' fosse necessaria al di fuori della macro (valore da riutilizzare 
nella funzione) io la riscriverei in modo da riceverla come argomento.
	#define LIKE_A_FUN(Y, X)
Cosi` il risultato di eventuali elaborazioni puo` essere assegnato ad 
una variabile qualsiasi.  Anche qui pensa alla mantenibilita` del codice.
4) Tutti i compilatori (o per lo meno quelli che ho usato io) non 
generano codice per il test while(0) quindi il codice generato nei due 
casi e` lo stesso.
Con questo non voglio dire che la tua macro sia sbagliata ma sicuramente 
l'uso del do{...}while(0) la rende molto piu` flessibile e, fino a che 
le funzioni inline non sono diventate standard, era il modo usato 
ovunque per creare l'equivalente (ed era altrettanto efficiente).
Ciao
Giovanni


 seh, allora bandiamo anche gli if\else perche sono simili a uno switch ;)
Era tanto per dire :) 

   print("stampa\n");
No che non si può! DEVI terminare con ';' se
vuoi avere la stessa notazione della
chiamata di funzione.
In questo caso è un vantaggio notazionale e stilistico.
Del resto se usi
 if (some_test)
   LIKE_A_FUN(10);
che in questo caso funziona, si potrebbe essere
indotti a pensare che la si può usare come in
 if (some_test)
   LIKE_A_FUN(10); /* con il ';' */
 else
   print("stampa\n");
Inducendo in errore.


 *Quale* efficienza ?
Fa N test invece di N+1 per uno statement ripetuto N volte.
Oppure migliore traduzione in assembler per un certo processore.


 le funzioni inline non sono diventate standard, era il modo usato
le inline sono gia' nello standard C99 - ma (a parte altri caveat) non 
e' detto che il codice venga necessariamente espanso in linea: con la 
dichiarazione 'inline', "suggerisci solamente" al compilatore di fare 
uno sforzo maggiore per rendere la chiamata alla funzione piu' veloce.


 ;;;;;;{;;{;;;;};;};;;;;;
Perche` io ho usato compilatori che davano errore.  Se non ricordo male 
era una delle vecchie versioni del compilatore intel (sia ic86 che 
ic386) degli anni  inizio '90.
Quelli piu` recenti correttamente non lo danno.


 dal loop e termina.
Grazie per tutte queste precisazioni, sei molto paziente :-)! Thank you a
lot!
Rocky3
-- 
"Il sapere e la ragione parlano, l'ignoranza ed il torto urlano".
Arturo Graf / Indro Montanelli / Anonimo