Ho cominciato fare un pò di esercizio ed ho provato a scrivere un programmino che svolge operazioni aritmetiche semplici utilizzando le prime elementari istruzioni del linguaggio:
/* calcola.c é un programma di calcolo in "C": 14-ago-2010
funzioni eseguibili
- Somma e Sottrazione: 14-ago-2010 */
#include <stdio.h>
int main()
{ /* Attenzione: il compilatore riconosce solo i primi 8 crt del nome di variabili o costanti */
int numins; /* destinazione del Numero digitato */
int totale; /* totalizzatore dei numeri digitati */
char segnoper[1]; /* Stringa di memorizzazione del tipo di operazione richiesta */
printf("\nDigita Numero:");
scanf("%d", &numins); /* lettura del numero digitato */
printf("numins: %d\n", numins);
totale = numins; /* valorizzazione iniziale del totalizzatore */
printf("Digita Segno operazione:");
scanf("%1s[-+=]", segnoper); /* lettura del segno-operazione digitato, con predisposizione a convalidare il 1° crt digitato */
printf("segnoper: %s\n", segnoper);
printf("totale: %d\n", totale);
printf("numins: %d\n", numins);
return ;
/* l'esecuzione si ferma qui perché proseguando va in loop */
while (segnoper != "=") /* fino a quando segno operazione <> "=" */
{
printf("Digita Numero e segno operazione:");
scanf("%d%s[-+=]", &numins, segnoper); /* lettura del numero digitato e del segno-operazione */
if (segnoper == "+")
{
totale += numins;
}
else
if (segnoper == "-")
{
totale -= numins;
}
}
printf("Risultato = %d\n", totale);
return 0;
}
All'esecuzione ottengo:
/$ /home-fedora/piero/C/calcola
Digita Numero:23
numins: 23
Digita Segno operazione:+
segnoper: +
totale: 23
numins: 0
Il campo 'numins' inizialmente viene valorizzato bene; il suo contenuto viene caricato anche in 'totale', però dopo la digitazione di 'segnoper', 'numins' torna inspiegabilmente a zero, come se si perdesse il puntamento all'indirizzo di memoria.
Sicuramente mi sfugge qualcosa.
:(
Il tuo problema dovrebbe esser qui:
scanf("%d%s[-+=]", &numins, segnoper)
prova con
scanf("%d,%s[-+=]", &numins, segnoper)
scanf("%d,%1s[-+=]", segnoper;
ha funzionato, però vorrei capire ... .
Nel libro che sto seguendo in aggiunta al tuo corso in e-zine ho letto fino ad ora esempi ed argomenti sui simboli di "specifica di conversine", scritti sempre l'uno di seguito all'altro, senza la frammissione di virgole.
Relativamente ad un esercizio relativo proprio a "scanf", per esempio, é scritto:
.......... bla bla ...............
15 scanf("%d%d, &num1, &num2); /* legge due interi */
.......... bla bla ...............
Osservate che il programma in Figura 2.13 utilizza scanf (riga 15) per prendere in input i due numeri. Ogni specifica di conversione ha un argomento corrispondente in cui dovrà essere immagazzinato un valore. Il primio %d convertirà un valore che sarà immagazzinato nella variabile num1 , mentre il secondo convertirà un valore che sarà immagazzinato nella variabile num2 .
Per me, la tua proposta di modifica é stata un'assoluta sorpresa; poi, magari bisogna vedere se il libro che sto leggendo non faccia riferimento ad un linguaggio C inserito in un S.O. diverso da Linux, per cui possano manifestarsi certe differenze di dettaglio. Una noticina in proposito può essere quella riportata in due righe della prefazione
Il testo segue lo standard ANSI C; tenete presente che molte funzionalità dell'ANSI C non sono implementate nelle versioni pre-ANSI del C. Per avere informazioni più dettagliate sul linguaggio vi conviene consultare il manuale di riferimento del vostro sistema o procurarvi una copia del documento ANSI/ISO 9899.
???
Intanto, grazie al tuo suggerimento, posso andare avanti, e così spero di fare da calamita ai prossimi volenterosi C-isti che volessero attivarsi a rendere più partecipata anche la presente sezione del Forum.
;D ;D
Ha ragione la seconda.
Se la tua volontà e creare un numero casuale allora devi fare così:
int i;
srand(time(NULL));
i = rand() % VALORMAX + 1;
Il codice è semplice. Dichiari la variabile intera i, inizializzi il seme del random, grazie ad srand(), con il valore attuale dell'orologio in modo che è quasi impossibile avere sempre lo stesso seme casuale. Infine assegni ad i un valore casuale generato da rand(). L'ultimo rigo è quello più criptitico. Infatti vedrai che c'è un modulo (%) e poi il valore massimo (VALOREMAX) più 1. Questo perchè? Rand genera un numero casuale. Se a noi serve un numero compreso tra 0 e VALOREMAX allora facciamo il modulo tra il numero generato e VALOREMAX in modo tale da essere sicuri che il numero ottenuto non superi il massimo da noi voluto. Fatto ciò incrementiamo di 1 perchè il valore che otterremo sarà VALOREMAX - 1 (resto di una divisione).
Lo so che non mi sono spiegato. Se hai dubbi chiedi pure e verò di essere più chiaro.
Posti qui il codice che va in loop?
#include <stdio.h>
int main()
{
float QuoDig = 0; /* Quota_Digitata */
float MontDig = 0; /* Montante_digitato */
float MontGlob = 20000.00; /* Montante_Globale */
float QuotaX = 0; /* Quota_Digitata */
int SiNo; /* 0 ==> SI ; -1==> NO */
printf ("\ndigita Quota (Importo parziale):");
scanf ("%.2f", &QuoDig);
-------------------------------------------------------------------------qui comincia il loop
while ( SiNo != -1 )
{
printf ("\ndigita Montante (Importo Globale):");
scanf( "%.2f", &MontDig );
QuotaX = QuoDig * MontDig / MontGlob;
printf ("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
printf ("Vuoi continuare ? (0=si , -1=No):");
scanf ("%.2f", &SiNo);
if (SiNo == -1)
{ break; }
else
{
printf ("\n\ndigita Quota (Importo parziale):");
scanf( "%.2f", &QuoDig );
}
---------------------------------------------------------------------------------------------- ciclo di loop
return 0;
}
Ma perchè hai inserito un controllo di tipo if sulla variabile SiNo? Tieni presente che while controlla da sè lo stato della variabile o della condizione posta come riferimento.....Inoltre con la tua scanf richiedi un valore che deve essere un float con doppio decimale quando invece devi solo darlo in pasto la variabile SiNo che è un intero.
#include <stdio.h>
int main()
{
float QuoDig = 0.0; /* Quota_Digitata */
float MontDig = 0.0; /* Montante_digitato */
float MontGlob = 20000.00; /* Montante_Globale */
float QuotaX = 0.0; /* Quota_Digitata */
int SiNo; /* 0 ==> SI ; -1==> NO */
printf ("\ndigita Quota (Importo parziale):");
scanf ("%.2f", &QuoDig);
while ( SiNo != -1 )
{
printf ("\ndigita Montante (Importo Globale):");
scanf( "%.2f", &MontDig );
QuotaX = QuoDig * MontDig / MontGlob;
printf ("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
printf ("Vuoi continuare ? (0=si , -1=No):");
scanf ("%d", &SiNo);
printf ("\n\ndigita Quota (Importo parziale):");
scanf( "%.2f", &QuoDig );
}
return 0;
}
prova con
#include <stdio.h>
int main()
{
float QuoDig = 0.0; /* Quota_Digitata */
float MontDig = 0.0; /* Montante_digitato */
float MontGlob = 20000.00; /* Montante_Globale */
float QuotaX = 0.0; /* Quota_Digitata */
int SiNo; /* 0 ==> SI ; 1==> NO */
do
{
printf ("\ndigita Quota (Importo parziale):");
scanf ("%.2f", &QuoDig);
printf ("\ndigita Montante (Importo Globale):");
scanf( "%.2f", &MontDig );
QuotaX = QuoDig * MontDig / MontGlob;
printf ("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
printf ("Vuoi continuare ? (0=si , 1=No):");
scanf ("%d", &SiNo);
} while ( SiNo != 1 )
return 0;
}
La funzione do...while é un pò avanti per me, comunque ho fatto come mi hai detto, però l'istruzione "}</stdio.h> " dell'ultima riga produce l'errore:
46: error: expected identifier or ‘(’ before ‘<’ token
, quindi l'ho dovuta eliminare. Il programma va sempre in loop.
Per quello che posso capire, detta istruzione dovrebbe servire a chiudere la libreria standard di C, ma é necessaria? Mai incontrata fino ad ora.
Prima del tuo suggerimento avevo provato con:
......bla.....bla.....bla...............................
int SiNo; /* 0 ==> SI -1 ==> NO
while ( SiNo != -1 )
{
printf("\n\ndigita Quota (Importo parziale):");
scanf("%.2f", &QuoDig);
printf("\ndigita Montante (Importo Globale):");
scanf("%.2f", &MontDig);
QuotaX = QuoDig * MontDig / MontGlob;
printf("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
printf("Vuoi continuare ? (0=si , -1=No):");
scanf("%d", &SiNo);
}
return 0;
Cioé avevo portato tutto dentro la funzione while, spostando la scanf("%d", &SiNo) alla fine dell'iterazione, proprio come da tua successiva proposta.
Il programma andava pur in loop.
Ho eliminato dal programma il ciclo while; pertanto le istruzioni rimaste sono solamente:
printf("\n\ndigita Quota (Importo parziale):");
scanf("%.2f", &QuoDig);
printf("\ndigita Montante (Importo Globale):");
scanf("%.2f", &MontDig);
QuotaX = QuoDig * MontDig / MontGlob;
printf("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
printf("Vuoi continuare ? (0=si , 1=No):");
scanf("%d", &SiNo);
return 0;
Ecco cosa succede:
digita Quota (Importo parziale):147.25
digita Montante (Importo Globale):
Quota proporzionale calcolata = 0.00
Vuoi continuare ? (0=si , 1=No):
piero@fedora-pct:~/C$
il codice va in loop indipendentemente da ciò che scegli? cioè si o no?
Il programma si ferma solamente alla 1^ digitazione float. Non appena conclusa col tasto INVIO va subito in loop. Perciò non riesco a fare alcuna scelta.
È un comportamento troppo strano....ho provato a fare una semplice prova (scusa ilo gioco di parole) e funziona...
# include <stdio.h>
int main()
{
int i;
while(i!=1)
{
printf("digiti: ");
scanf("%d", &i);
}
return 0;
}
Ho modificato per prova il mio programmino:
#include <stdio.h>
int main()
{
int QuoDig = 0; /* Quota_Digitata */
float MontDig = 0; /* Montante_digitato */
float MontGlob = 210000.00; /* Montante_Globale */
float QuotaX = 0; /* Quota_Digitata */
int SiNo; /* 0 ==> SI 1 ==> NO */
while ( SiNo != 1 )
{
printf("\n\ndigita Quota (Importo parziale):");
scanf("%d", &QuoDig);
printf("Vuoi continuare ? (0=si , 1=No):\n");
scanf("%d", &SiNo);
}
return 0;
}
Come puoi vedere ho lasciato solo le variabili int. Così facendo la funzione while funziona perfettamente ed il loop é scomparso. Quindi il problema é l'utilizzo delle variabili float. É necessario perciò che capisca come gestire i numeri in virgola mobile, dall'immissione da tastiera fino alla stampa.
Già avere scoperto la natura del problema é una gran cosa.
:)
Ciao.
Finalmeeeeeeenteee ♬♬♩♫ ;D
Ce l'ho fatta. Come? Modificando il carattere di formattazione in ciascuna scanf per la lettura di valori float:
scanf("%.2f", &variabile
scanf("%f", &variabile);
mentre la printf é rimasta inalterata
printf("\nQuota proporzionale calcolata = %.2f\n", QuotaX);
Probabilmente, all'atto dell'immissione, non é prevista la lunghezza dei decimali. É possibile?
:) :D ;D
Ciao.