Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Programma calcolatrice
Forum - C/C++ - Programma calcolatrice

Avatar
fatshady (Normal User)
Newbie


Messaggi: 5
Iscritto: 02/06/2010

Segnala al moderatore
Postato alle 21:42
Mercoledì, 02/06/2010
Ciao, volevo chiedervi una mano per interpretare questo codice, il nostro prof ce l'ha fornito e dobbiamo fare una relazione. A scuola non studiamo C, il prof ce l'ha spiegato ma ho capito molto poco...:d riuscireste a dirmi cosa fanno le varie funzioni? dovrei portarla per venerdi ma mi son ricordato solo ora che dovevo farla. Se riuscite a darmi una mano ve ne sarei grato se non fate in tempo per venerdi scriverò quello che ho capito da solo :)

Codice sorgente - presumibilmente C

  1. ecco il codice :
  2.  
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5.  
  6. #define MAXOP 100
  7. #define NUMBER '0'
  8.  
  9. int getop(char []);
  10. void push(double);
  11. double pop(void);
  12.  
  13. /* reverse polish calculator */
  14.  
  15. int main(void)
  16. {
  17.         int type;
  18.         double op2;
  19.         char s[MAXOP];
  20.  
  21.         while((type = getop(s)) != EOF)
  22.         {
  23.                 switch(type)
  24.                 {
  25.                                 case NUMBER:
  26.                                                 push(atof(s));
  27.                                                 break;
  28.                                 case '+':
  29.                                                 push(pop()+pop());
  30.                                                 break;
  31.                                 case '*':
  32.                                                 push(pop()*pop());
  33.                                                 break;
  34.                                 case '-':
  35.                                                 op2 = pop();
  36.                                                 push(pop()-op2);
  37.                                                 break;
  38.                                 case '/':
  39.                                                 op2 = pop();
  40.                                                 if(op2 != 0.0)
  41.                                                         push(pop()/op2);
  42.                                                 else
  43.                                                         printf("error:zero divisor\n");
  44.                                 case '\n':
  45.                                                 printf("\t%.8g\n",pop());
  46.                                                 break;
  47.                                 default:
  48.                                                 printf("error: unknown command %s\n",s);
  49.                                                 break;
  50.                 }
  51.         }
  52.         return 0;
  53. }
  54.  
  55.  
  56. #define MAXVAL 100
  57.  
  58. int sp = 0;
  59. double val[MAXVAL];
  60.  
  61. void push(double f)
  62. {
  63.         if(sp < MAXVAL)
  64.                 val[sp++]=f;
  65.         else
  66.                 printf("error:stack full, cant push %g\n",f);
  67. }
  68.  
  69.  
  70. double pop(void)
  71. {
  72.         if(sp>0)
  73.                 return val[--sp];
  74.         else
  75.         {
  76.                 printf("error: stack empty\n");
  77.                 return 0.0;
  78.         }
  79. }
  80.  
  81. #include<ctype.h>
  82.  
  83. int getch(void);
  84. void ungetch(int);
  85.  
  86. int getop(char s[])
  87. {
  88.         int i,c;
  89.  
  90.         while((s[0] = c = getch()) == ' ' || c =='\t')
  91.                 ;
  92.         s[1] = '\0';
  93.         if(!isdigit(c) && c!='.')
  94.                 return c;
  95.        
  96.         i = 0;
  97.         if(isdigit(c))
  98.                 while(isdigit(s[++i] =c =getch()))
  99.                         ;
  100.  
  101.         if(c=='.')
  102.                 while(isdigit(s[++i] = c=getch()))
  103.                         ;
  104.        
  105.         s[i] = '\0';
  106.         if(c!=EOF)
  107.                 ungetch(c);
  108.         return NUMBER;
  109. }
  110.  
  111. #define BUFSIZE 100
  112.  
  113. char buf[BUFSIZE];
  114. int bufp = 0;
  115.  
  116. int getch(void)
  117. {
  118.         return (bufp > 0) ? buf[--bufp] : getchar();
  119. }
  120.  
  121. void ungetch(int c)
  122. {
  123.         if(bufp >= BUFSIZE)
  124.                 printf("ungetch: too many characters\n");
  125.         else
  126.                 buf[bufp++] = c;
  127. }


PM Quote
Avatar
napco (Normal User)
Pro


Messaggi: 64
Iscritto: 16/04/2010

Segnala al moderatore
Postato alle 0:12
Giovedì, 03/06/2010
Ciao! Analizzare un programma è una cosa fondamentale da imparare. Da quello che mi sembra di vedere non sembra poi tutta questa difficoltà. Facciamo così: Se conosci l'inglese prova a leggerti la guida di Beej sul linguaggio C (la trovi su google), e prova da solo a capirlo. Se proprio vedi che non ce la fai entro venerdì fammi sapere e ti spiego tutto io.

PM Quote
Avatar
fatshady (Normal User)
Newbie


Messaggi: 5
Iscritto: 02/06/2010

Segnala al moderatore
Postato alle 0:29
Giovedì, 03/06/2010
il fatto è a scuola noi programmiamo in c#, al prof di sistemi però, adesso alla fine dell anno gli è venuto in mente di farci vedere qualcosa in c anche se a scuola nn lo facciamo...come ho gia detto qualcosina ho capito di questo programma, e ho intenzioe di imparare qualcosa in C per vedere le cose piu a basso livello ma per conto mio quando ho tempo. In queste ultime 2 settimane di scuola sto tirando un po le somme e non ho proprio tempo per dedicarmici.Hai perfettamente ragione che dovrei capirlo da solo altrimenti risulta poco efficace farmelo spiegare cosi veloce ma non ho proprio tempo ora, comunque darò certamente un occchiata alla guida che mi hai consigliato, non consco benissimo l inglese ma ci provo.
Probabilmente riesco a collegarmi solo domani dopo mezzogiorno quindi se hai tempo e voglia di darmi una mano puoi scrivere anche domani mattina, pomeriggio o sera tanto vado sempre a letto tardi...

Grazie ancora !

PM Quote
Avatar
Ultimo (Member)
Guru


Messaggi: 877
Iscritto: 22/05/2010

Segnala al moderatore
Postato alle 16:39
Giovedì, 03/06/2010
Il C equivale a sapere le basi del C# che è una sua evoluzione.


If ok Then GOTO Avanza else GOTO Inizia

PM Quote
Avatar
fatshady (Normal User)
Newbie


Messaggi: 5
Iscritto: 02/06/2010

Segnala al moderatore
Postato alle 17:43
Giovedì, 03/06/2010
è un evoluzione ma come puoi vedere dal codice questo programma lavora molto a basso livello... per quanto ne so non penso sia realizzabile in c#...

PM Quote
Avatar
fatshady (Normal User)
Newbie


Messaggi: 5
Iscritto: 02/06/2010

Segnala al moderatore
Postato alle 1:27
Venerdì, 04/06/2010
Ho finito adesso di scrivere la relazione... i concetti li ho messi come commenti nel codice qui sotto.. napco dimmi poi se ho capito bene :)

Codice sorgente - presumibilmente C

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. #define MAXOP 100
  5. #define NUMBER '0'
  6.  
  7. int getop(char []);
  8. void push(double);
  9. double pop(void);
  10.  
  11. /* reverse polish calculator */
  12.  
  13. int main(void)
  14. {
  15.         int type;
  16.         double op2;
  17.         char s[MAXOP];
  18.  
  19.         while((type = getop(s)) != EOF) //  finche type è diverso dal carattere di fine file
  20.         {
  21.                 switch(type)
  22.                 {
  23.                                 case NUMBER:                            //se è il carattere 0 ovvero se s contiene un numero
  24.                                                 push(atof(s)); //converto stringa in float e lo metto nello stack
  25.                                                 break;
  26.                                 case '+':
  27.                                                 push(pop()+pop());
  28.                                                 break;
  29.                                 case '*':
  30.                                                 push(pop()*pop());
  31.                                                 break;
  32.                                 case '-':
  33.                                                 op2 = pop();
  34.                                                 push(pop()-op2);
  35.                                                 break;
  36.                                 case '/':
  37.                                                 op2 = pop();
  38.                                                 if(op2 != 0.0)
  39.                                                         push(pop()/op2);
  40.                                                 else
  41.                                                         printf("error:zero divisor\n");
  42.                                 case '\n':                                                                                                      // il caattere è invio stampa il risultato che è in cima alla pila.
  43.                                                 printf("\t%.8g\n",pop());
  44.                                                 break;
  45.                                 default:                                                                                                        // se il carattere non è nessuno di questi stampa l erore
  46.                                                 printf("error: unknown command %s\n",s);
  47.                                                 break;
  48.                 }
  49.         }
  50.         return 0;
  51. }
  52.  
  53.  
  54. #define MAXVAL 100
  55.  
  56. int sp = 0;
  57. double val[MAXVAL];
  58.  
  59. void push(double f)
  60. {
  61.         if(sp < MAXVAL)
  62.                 val[sp++]=f;
  63.         else
  64.                 printf("error:stack full, cant push %g\n",f);
  65. }
  66.  
  67.  
  68. double pop(void)
  69. {
  70.         if(sp>0)
  71.                 return val[--sp];
  72.         else
  73.         {
  74.                 printf("error: stack empty\n");
  75.                 return 0.0;
  76.         }
  77. }
  78.  
  79. #include<ctype.h>
  80.  
  81. int getch(void);
  82. void ungetch(int);
  83.  
  84. int getop(char s[])
  85. {
  86.         int i,c;
  87.  
  88.         while((s[0] = c = getch()) == ' ' || c =='\t') // prendo un carattere, finche è uno spazio o una tab non fare nulla
  89.                 ;
  90.         s[1] = '\0';                                                                    // a questo punto s0 è un carattere e mettiamo \0 per dire che dinisce qui la stringa
  91.         if(!isdigit(c) && c!='.')                                               // isdifit ritorna 1 se il carattere è un numero. se NON è un nuemro è non è un punto ritorna C
  92.                 return c;
  93.        
  94.         i = 0;                                                                                  //
  95.         if(isdigit(c))                                                                  // se c è u numero
  96.                 while(isdigit(s[++i] =c =getch()))                      // finche il carattere è u numero riempi l array s.
  97.                         ;
  98.  
  99.         if(c=='.')                                                                              // se c è un punto continua a prendere numeri
  100.                 while(isdigit(s[++i] = c=getch()))
  101.                         ;
  102.        
  103.         s[i] = '\0';                                                                    // metto il carattere di fine stringa
  104.         if(c!=EOF)                                                                              // se c è diverso dal carattere di fine file
  105.                 ungetch(c);                                                                     // metti c nel buffer
  106.         return NUMBER;                                                                  // ritorna il carattere 0.
  107. }
  108.  
  109. #define BUFSIZE 100
  110.  
  111. char buf[BUFSIZE];      //il nostro buffer da 100 caratteri
  112. int bufp = 0;       // numero elementi nel buffer
  113.  
  114. int getch(void)
  115. {
  116.         return (bufp > 0) ? buf[--bufp] : getchar(); //se nel buffer ce qualcosa lo prende altrimente prende nuovo carattere getchar è una fuznione contenuta nella libreria standard
  117. }
  118.  
  119. void ungetch(int c)
  120. {
  121.         if(bufp >= BUFSIZE)                     // SE NON CE SPAZIO NEL BUFFER scrivri stringa
  122.                 printf("ungetch: too many characters\n");
  123.         else{                                                   // altrimenti aggiungi C al buffer
  124.                
  125.                 buf[bufp++] = c;
  126.                 }
  127. }


PM Quote
Avatar
napco (Normal User)
Pro


Messaggi: 64
Iscritto: 16/04/2010

Segnala al moderatore
Postato alle 2:31
Venerdì, 04/06/2010
Adesso come adesso non mi pare di vedere errori, comunque c'è da dire che ad una relazione strutturata in questo modo, se fossi un prof, non darei una valutazione troppo alta. Mi pare che tu ti sia limitato a parafrasare il codice, ma il senso del programma l'hai capito? Quello che hai scritto va bene, ma cerca di elaborare la tua parafrasi in un riassuntino discorsivo del programma. es:

Questo programma non è altro che una calcolatrice che accetta come input dei numeri e li immagazzina in uno stack. Nel momento in cui viene inserito un carattere corrispondente ad un operatore, il programma estrae gli ultimi 2 numeri dallo stack, ne valuta la somma/differenza/ecc... e ne reinserisce il risultato nello stack stesso, finchè non viene inserito il carattere '\n', che stampa a schermo il valore che si trova in cima alla pila (risultato).

PM Quote
Avatar
fatshady (Normal User)
Newbie


Messaggi: 5
Iscritto: 02/06/2010

Segnala al moderatore
Postato alle 22:15
Venerdì, 04/06/2010
no questa non è la relazione ! :) praticamente questo l'ho scritto prima per avere uno schema di come funzionava il programma! poi ho fatto la relazione esattamente come dice te.. in modo discorsivo e ho aggiunto un diagramma di flusso(che spero dia ver fatto giusto) :). lo postato per capire se avevo capito... per esempio dove spiego le varie funzioni ho scritto :

La funzione getop
Questa funzione prende come argomento un array di caratteri e restituisce un intero.
Attraverso il promo while vengono scartati tutti i caratteri di spazio e di tabulazione, successivamente quando verrà premuto un carattere che non sia fra questi viene inserito il carattere di fine stringa “\0”.     Se il carattere inserito non sarò u numero la funzione ritornerà questo valore
Se il carattere inserito è u numero, Il secondo while verifica che l’utente voglia scrivere un numero con la virgola effettuando un controllo sul carattere scrittto, se risulta essere un “.” Il ciclo provvederà a contiuare a ricevere caratteri di tipo numero.
Quando il carattere non sarà piu un numero verrà messo il sibolo di fine stringa e prima di ritornare si verifica che questo valore non sia il carattere che identifica l EOF (End of file), se non è quel carattere il valore verrà caricato in un buffer che implementiamo attraverso al funzione ungetch, in modo da essere salvato.

La funzione main
Questa funzione è la principale, presente in ogni programma scritto in C.
Tramite il while iniziale e un costrutto switch-case confrontiamo i diversi casi che possiamo ottenere : se la fuznione getop richiamata nel while ritorna uno zero significa che il carattere inserito è un numero e verrà inserito nello stack; se il carattere è quello di invio verrà stampato il valore in cima alla pila; se il valore ritornato non è nessuono di quelli presenti nei case verrà stampato un messaggio d’ errore e se il carattere è un operatore tramite le pop verrà eseguito il calcolo riportando il risultato in cima allo stack attraverso la funzione push.

La funzione getch
Questa funzione non prende in ingresso nessun valore e restituisce un carattere letto da tastiera.
Questa funzione viene chiamata ogni volta che il programma necessita di un carattere, se il buffer contiene dei valori verranno estratti altrimenti verrà letto un carattere da tastiera.

La funzione ungetch
Questa funzione prende in ingresso un intero che verrà caricato nel buffer a meno che il buffer non sia pieno.

Le funzioni di push e pop
Tramite queste due funzioni implementiamo un stack nel nostro programma necessario per eseguire il calcoli.

Vi sembra giusta la spiegazione delle funzioni?

PM Quote