Ciao a tutti. Prima di parlare dell'esercizio vorrei fare una domanda sui puntatori.
Nei programmi che prevedono l'esecuzione da riga di comando, per considerare la stringa corrispondente all'argomento 0, ad esempio nel caso in cui volessi passare la stringa come argomento in una funzione, dovrei scrivere *argv[0], questa scrittura è equivalente ad *argv e fin qui ci sono.
Visto però che l'oggetto in questione è una stringa, esso corrisponde all'indirizzo del primo carattere, allora scrivere argv[0] senza asterisco, che sarebbe l'indirizzo dell'argomento zero, in questo caso equivale alle altre due scritture, visto l'argomento zero è un vettore e il suo valore equivale all'indirizzo del primo carattere della stringa?
Passando all'esercizio. Chiede di scrivere un programma eseguibile da linea di comando, che valuta espressioni in notazione Polacca inversa. Siccome al capitolo 4 paragrafo 3 c'è un esempio di programma che valuta queste espressioni, non ho dovuto scrivere l'intero programma, ma solo modificare questo.
La modifica più consistente è sulla funzione getop, che prende come argomento un carattere anzichè una stringa:
#include <ctype.h>
int getop(char c)
{
if (isdigit(c) && c!= '.')
return c;
else
return NUMBER
}
Le altre modifiche appartengono al main: il ciclo while, la cui durata sarà uguale a quella di argc-1 (visto che il primo argomento è il nome del programma) e l'assegnamento a type che viene spostato all'interno del ciclo (l'argomento passato a getop sarà il primo carattere della stringa dell'argomento prossimo (*++argv)[0]), infine negli altri posti in cui si usava la stringa s, viene passata invece la stringa dell'argomento corrente *argv. (il vettore s non serve più in quanto gli operandi e gli operatori sono già salvati in argv.)
Le funzioni push e pop rimangono invariate.
#include <stdio.h>
#include <math.h>
#define MAXOP 100
#define NUMBER ’0’
int getop(char s[]);
void push(double);
double pop(void);
main()
{
int type;
double op2;
while (--argc > 0)
{
type = getop( (*++argv)[0] );
switch (type) {
case NUMBER:
push(atof(*argv));
break;
case ’+’:
push(pop()+pop());
break;
case ’*’:
push(pop()*pop());
break;
case ’-’:
op2=pop();
push(pop()-op2);
break;
case ’/’:
op2=pop();
if (op2!=0.0)
push(pop()/op2);
else
printf(“Errore: divisione per zero\n”);
break;
case ’\n’:
printf(“\t%.8g\n”, pop());
break;
default:
printf(“Errore: comando %s sconosciuto\n”, *argv);
break;
}
}
return 0;
}
/* Funzioni push e pop */
#define MAXVAL 100
int sp = 0;
double val[MAXVAL];
void push(double f)
{
if (sp<MAXVAL)
val[sp++]=f;
else
printf(“Errore: stack pieno; %g non inseribile\n”, f);
}
double pop(void)
{
if (sp>0)
return val[sp—];
else {
printf(“Errore: lo stack è vuoto\n”);
return 0.0;
}
}