Autore Topic: Prime difficoltà col 'C'  (Letto 4227 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Prime difficoltà col 'C'
« il: 26 Agosto 2010, 16:55:22 »
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:
Codice: c [Seleziona]
/* 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 */


Codice: [Seleziona]
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:
Citazione
/$ /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.
 :(
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #1 il: 26 Agosto 2010, 17:04:55 »
Il tuo problema dovrebbe esser qui:

Codice: [Seleziona]
scanf("%d%s[-+=]", &numins, segnoper)

prova con

Codice: [Seleziona]
scanf("%d,%s[-+=]", &numins, segnoper)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #2 il: 28 Agosto 2010, 15:52:33 »
Codice: [Seleziona]
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:
Citazione
Codice: [Seleziona]
.......... 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
Citazione
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
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #3 il: 28 Agosto 2010, 18:07:45 »
Guarda, la cosa l'ho buttata giù lì.....fa piacere che abbia funzionato...magari è solo un errore di stampa....capita a volte....comunque l'ANSI C è l'attuale versione evoluzione dello standard C che ha introdotto alcune cose particolari e tutti i libri ora come ora fanno riferimento a questo C....

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #4 il: 04 Settembre 2010, 17:19:04 »
fra le funzioni della libreria matematica <math.h> ho trovato la rand().
Ebbene, in questo documento trovo la seguente indicazione
Citazione
int rand (void) - Get a random integer between 0 and 32.
in quest'altro  leggo:
Citazione
i = rand ();
genera un intero compreso tra 0 e RAND_MAX, valore definito nella libreria <stdlib.h>
(che dovrete quindi sempre includere nell’usare questo operatore).
Il valore di RAND_MAX nello standard ANSI è almeno 32767.
???
Chi ha ragione?
Ciao

:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #5 il: 04 Settembre 2010, 17:31:34 »
Ha ragione la seconda.

Se la tua volontà e creare un numero casuale allora devi fare così:

Codice: c [Seleziona]
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.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #6 il: 04 Settembre 2010, 23:29:53 »
Grazie del chiarimnto. Per ora non sto applicando le funzioni rand, randomize, srand; sto solamente cercando di capire come funzionano, mentre passo da una banco all'altro del magazzino di "C".  ;)

Ciao, però una volta c'era una bella emoticon che salutava col sorriso sulle labbre, mentre ora la faccina ha le labbra che denotano tristezza, una tristezza tendente alle lacrime, allora non saluto più con lla faccina dell'emoticon, ma saluto, scrivendo proprio:
Cao, ciao.  :)
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #7 il: 10 Settembre 2010, 15:38:16 »
Attualmente sto provando ad usare la funzione while, però non riesco a fare funzionare il programma; infatti va in loop dentro la funzione, senza mai fermarsi; non sente nemmeno i comandi scanf per l'immissione dati. Dopo il 1° scanf, entra nella funzione while e non si ferma più. Però copiando gli esercizi del mio libro, funziona tutto perfettamente.
 >:(  :'(
Un'altra notizia: come faccio a stoppare un programma in loop? Ho provato col tasto "Break", coi tasti "Canc", "Ctrl+Canc", "Alt+Canc", "Esc", "Ctrl+Esc", "Alt+Esc", ma sempre senza successo.
Ciao.
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #8 il: 10 Settembre 2010, 15:45:16 »
Attualmente sto provando ad usare la funzione while, però non riesco a fare funzionare il programma; infatti va in loop dentro la funzione, senza mai fermarsi; non sente nemmeno i comandi scanf per l'immissione dati. Dopo il 1° scanf, entra nella funzione while e non si ferma più. Però copiando gli esercizi del mio libro, funziona tutto perfettamente.
 >:(  :'(
Un'altra notizia: come faccio a stoppare un programma in loop? Ho provato col tasto "Break", coi tasti "Canc", "Ctrl+Canc", "Alt+Canc", "Esc", "Ctrl+Esc", "Alt+Esc", ma sempre senza successo.
Ciao.


Posti qui il codice che va in loop?

per fermare un programma, vale in generale nella shell, basta premere CRTL+C

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #9 il: 10 Settembre 2010, 16:50:46 »
Posti qui il codice che va in loop?

Codice: [Seleziona]
#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; 
}
« Ultima modifica: 10 Settembre 2010, 17:02:16 da Ceskho »
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #10 il: 10 Settembre 2010, 17:11:02 »
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.

Codice: c [Seleziona]
#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;  
}

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #11 il: 10 Settembre 2010, 18:00:54 »
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.
Il controllo di tipo if sulla variabile SiNo é la conseguenza di tante prove fatte nel tentativo di non vedere più l'effetto loop sulla shell.
la scanf in questione  scanf ("%.2f", &SiNo); contiene effettivamente un valore di formattazione errato, a causa di un copia&incolla corretto poi solo parzialmente.

Si, se vogliamo sono errori logici, ma ininfluenti nei riguardi del loop; infatti ho sostituito il mio codice con quello che gentilmente mi hai restituito, con le correzioni, ed ho ottenuto sempre l'effetto loop sulla consolle, con un'interrota sequenza di righe come le seguenti:
Citazione
digita Quota (Importo parziale):
digita Montante (Importo Globale):
Quota proporzionale calcolata =  0.00
Vuoi continuare ?  (0=si ,  -1=No):

digita Quota (Importo parziale):
digita Montante (Importo Globale):
Quota proporzionale calcolata =  0.00
Vuoi continuare ?  (0=si ,  -1=No):

Persiste  sicuramente una banalità che non riesco a vedere. Ma quale?  ???
Ciao.
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #12 il: 10 Settembre 2010, 18:33:04 »
prova con

Codice: c [Seleziona]
#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;   
}
« Ultima modifica: 10 Settembre 2010, 18:37:02 da Ceskho »

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Prime difficoltà col 'C'
« Risposta #13 il: 10 Settembre 2010, 19:06:19 »
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:
Codice: [Seleziona]
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:
Codice: [Seleziona]
......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.
« Ultima modifica: 10 Settembre 2010, 19:10:36 da Picavbg »
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Prime difficoltà col 'C'
« Risposta #14 il: 10 Settembre 2010, 19:11:52 »
L'errore che ricevi è dovuto ad un bug del sistema che c'è qui sul forum di evidenziazione della sintassi...in pratica riconosce <stdio.h> tipo un tag e le chiude automaticamente con un </stdio.h>....basta cancellare, come hai fatto, la stringa superflua </stdio.h>.

Tornando a noi: il codice va in loop indipendentemente da ciò che scegli? cioè si o no?

P.S. do-while e while svolgono lo stesso lavoro...è uguale...:-)