DOMANDA Semplice Programma Di Moltiplicazione

DD7

Nuovo Utente
17
1
Ho un problema con questo programma che acquisisce 3 numeri, e verifica che il risultato della moltiplicazione dei primi due sia uguale al terzo numero inserito.
C:
#include <stdio.h>
#include <stdlib.h>
 main() {int x,y;
        float z,ris;
        printf("Inserisci due numeri che vuoi moltiplicare, e l'apparente risultato \n\n\n\n");
        scanf("%d %d %d",&x,&y,&z);
    ris=0;
    ris=x*y;
    if(ris==z)
    {printf("Bravo, è  corretto!");}
    else
    {printf("Risposta errata!Il risultato e':");
    printf("=%f",ris);}
    system ("pause");
    return 0;
}
Ciò che non mi torna è perchè se lo compilo e lancio su Dev-c++, quest'ultimo è come se invertisse il mio ciclo if, ovvero, in caso di condizione vera, mi fa apparire "Risposta errata..etc"... Funziona solamente se nella condizione If vi immetto ris!=z . Perchè?Qualcuno sa dove è l'errore?Grazie :)
 
Ultima modifica da un moderatore:

movlw

Nuovo Utente
32
6
CPU
AMD A4 5300
Dissipatore
Default
Scheda Madre
AsRock DG3+
HDD
Toshiba 500GB
RAM
Kingstone 8GB DDR3
GPU
APU HD7480D
Monitor
Benq FP71G+
PSU
ITEK
OS
Windows 10 64bit
Prima di tutto faresti bene ad usare i tag per inserire il codice sul forum. Poi dovresti imparare ad indentare il codice perché così come è non è leggibile.
Codice:
if(condizione)
{
   istruzione;
   istruzione;
   ....
}
Le parentesi graffe devono essere allineate e stare sotto alle istruzioni che precedono un blocco. Il tuo modo di (non) indentare è pessimo, e sicuramente adottato da un docente di un ITIS. Scordatelo il prima possibile!

In secondo luogo ti devo comunicare che Dev C++ è una schifezza e non dovrebbe mai essere usato! Esistono soluzioni eccellenti e gratuite come l'IDE di OpenWatcom con relativi tool(http://www.openwatcom.org) e il compilatore Digital Mars(http://www.digitalmars.com), oppure c'è Visual Studio. Mai usare mingw e Dev C++! Leggi http://www.ioprogrammo.it/index.php?topic=19852.0

system("pause") è una schifezza per due motivi:
1) Non è standard. Funziona su Windows, ma non su altri sistemi operativi. Inoltre non è previsto dall'ANSI C.
2) È estremamente poco performante: è come usare una bomba atomica per schiacciare una zanzare fastidiosa. Usa getchar() o se proprio getch() con compilazione condizionale.
Venendo al tuo problema:
Codice:
#include <stdio.h>
#include <stdlib.h>
#define BUFF_SIZE (128)
int main(void)
{
   long x;
    long y;
    long z;
    char buff[BUFF_SIZE];
    char p;
    (void) fputs("Inserire il moltiplicando: ", stdout);
    if(NULL == fgets(buff, BUFF_SIZE, stdin))
    {
        /* Errore */
        return (EXIT_FAILURE);
    }
    /* Converte la stringa letta in un intero con segno in base 10 */
    x = strtol(buff,&p,10);
    if('\0' != *p)
    {
        /* errore da gestire */
        return (EXIT_FAILURE);
    }
    /* leggi gli altri dati come sopra*/
   /* Confrotta il prodotto*/
    return (EXIT_SUCCESS);
}
Ovviamente sarebbe opportuno scrivere una funzione che legga interi input.
 
Ultima modifica:
  • Mi piace
Reazioni: DD7

rodhellas

Utente Èlite
1,522
427
CPU
Ryzen 5 3600
Dissipatore
GELID Phantom
Scheda Madre
MSI B450 Gaming Plus Max
HDD
500GB m.2 + 2TB HDD
RAM
16GB Corsair LPX 3000mhz
GPU
Gigabyte GTX 960 OC
Audio
Integrata
Monitor
SyncMaster 223BW
PSU
Antec HCG-520M
Case
Meshify C
Net
Gigabit Fastweb
OS
Windows 10 64bit
Codice:
#include <stdio.h>
#include <stdlib.h>
#define BUFF_SIZE (128)
int main(void)
{
   long x;
    long y;
    long z;
    char buff[BUFF_SIZE];
    char p;
    (void) fputs("Inserire il moltiplicando: ", stdout);
    if(NULL == fgets(buff, BUFF_SIZE, stdin))
    {
        /* Errore */
        return (EXIT_FAILURE);
    }
    /* Converte la stringa letta in un intero con segno in base 10 */
    x = strtol(buff,&p,10);
    if('\0' != *p)
    {
        /* errore da gestire */
        return (EXIT_FAILURE);
    }
    /* leggi gli altri dati come sopra*/
   /* Confrotta il prodotto*/
    return (EXIT_SUCCESS);
}
Ovviamente sarebbe opportuno scrivere una funzione che legga interi input.
Ma ti complichi la vita e basta cosi :oogle:
@DD7 devi mettere z intero, non float. Un int non sarà mai uguale ad un float. E occhio al return, ritorni 0 in un main che non deve ritornare nulla.
 
  • Mi piace
Reazioni: DD7

movlw

Nuovo Utente
32
6
CPU
AMD A4 5300
Dissipatore
Default
Scheda Madre
AsRock DG3+
HDD
Toshiba 500GB
RAM
Kingstone 8GB DDR3
GPU
APU HD7480D
Monitor
Benq FP71G+
PSU
ITEK
OS
Windows 10 64bit
Ma ti complichi la vita e basta cosi :oogle:
@DD7 devi mettere z intero, non float. Un int non sarà mai uguale ad un float. E occhio al return, ritorni 0 in un main che non deve ritornare nulla.
Mi spiace, non mi trovi d'accordo. Non si tratta di complicarsi la vita, si tratta di apprendere come si scrivono correttamente i programmi in C. Non importa se si tratta di un esercizio scolastico: bisogna sempre cercare di risolvere gli esercizi usando tutte le proprie risorse. Accontentandosi di soluzioni che "tanto compilano" non è l'approccio giusto.

Inoltre ti faccio notare che quando non viene specificato il tipo di ritorno di una funzione, lo standard ANSI/C prevede che il compilatore assuma int come tipo di default. Perciò quello che ha scritto DD7 equivale completamente a
Codice:
int main()
{
    ...
}
che è comunque sbagliato perché ci sono solo due modi di scrivere il main correttamente (per i PC mainstream):
1)
Codice:
int main(void)
{
    return (EXIT_SUCCESS);
}
oppure se occorrono argomenti da linea di comando
Codice:
int main(int argc, char **argv) /*oppure char *argv[] */
{
    return (EXIT_SUCCESS);
}
Qualsiasi altra forma è errata, quando si parla di computer standard. Solo nei sistemi embedded si può trovare il main scritto così:
Codice:
void main(void)
{
 
}
perché i microcontrollori basilari non hanno nulla da restituire. Ma questo è un caso particolare che capita solo per le MCU, per il resto vale quanto esposto sopra.
 
  • Mi piace
Reazioni: DD7

rodhellas

Utente Èlite
1,522
427
CPU
Ryzen 5 3600
Dissipatore
GELID Phantom
Scheda Madre
MSI B450 Gaming Plus Max
HDD
500GB m.2 + 2TB HDD
RAM
16GB Corsair LPX 3000mhz
GPU
Gigabyte GTX 960 OC
Audio
Integrata
Monitor
SyncMaster 223BW
PSU
Antec HCG-520M
Case
Meshify C
Net
Gigabit Fastweb
OS
Windows 10 64bit
Mi spiace, non mi trovi d'accordo. Non si tratta di complicarsi la vita, si tratta di apprendere come si scrivono correttamente i programmi in C. Non importa se si tratta di un esercizio scolastico: bisogna sempre cercare di risolvere gli esercizi usando tutte le proprie risorse. Accontentandosi di soluzioni che "tanto compilano" non è l'approccio giusto.

Inoltre ti faccio notare che quando non viene specificato il tipo di ritorno di una funzione, lo standard ANSI/C prevede che il compilatore assuma int come tipo di default. Perciò quello che ha scritto DD7 equivale completamente a
Codice:
int main()
{
    ...
}
che è comunque sbagliato perché ci sono solo due modi di scrivere il main correttamente (per i PC mainstream):
1)
Codice:
int main(void)
{
    return (EXIT_SUCCESS);
}
oppure se occorrono argomenti da linea di comando
Codice:
int main(int argc, char **argv) /*oppure char *argv[] */
{
    return (EXIT_SUCCESS);
}
Qualsiasi altra forma è errata, quando si parla di computer standard. Solo nei sistemi embedded si può trovare il main scritto così:
Codice:
void main(void)
{
 
}
perché i microcontrollori basilari non hanno nulla da restituire. Ma questo è un caso particolare che capita solo per le MCU, per il resto vale quanto esposto sopra.

Per il main mi ricordavo che bisognasse sempre scrivere il tipo di ritorno, errore mio.
Per il resto, ovviamente è giusto come dici te, ma stiamo comunque parlando di una persona che presumo sia ancora agli inizi nello studio del C e secondo me dovrebbe concentrarsi sul capire bene le basi. Perchè sono d'accordo che usare scanf o simili non sia molto "sicuro", ma sparagli un fputs, fgets e strtol all'inizio non penso lo aiuti.
 
  • Mi piace
Reazioni: DD7

DD7

Nuovo Utente
17
1
Grazie mille a entrambi che han risposto, ora funziona tutto!!:) A dire la verità lo sto imparando da autodidatta poichè la mia sorellina alle superiori aveva bisogno di un grosso aiuto in materia e cerchiamo procedere insieme con i suoi appunti dati dalla sua professoressa, dato che a suo tempo alle superiori studiai Pascal e ho riscontrato qualche somiglianza! Scusatemi enormemente l'identazione pessima, ma quando ho aperto questa discussione ero di fretta e non mi ero soffermata su tale, avete pienamente ragione ç_ç Purtroppo per quanto riguarda dev, loro devono utilizzare per forza quello poichè se ne servono durante il compito in classe ahimè.. Grazie ancora!!
 

Fenix27

Utente Attivo
863
220
Ecco a te una versione più semplificata.
Alcuni accorgimenti:
- Non usare Dev-C++, non viene più aggiornato da anni e non lo usa più nessuno. Ti consiglio di scaricare Code::Blocks.
- Riguardo al 'system("pause");' non usarlo come detto da @mowlv non è consigliato e non fa parte dell'ANSI C. Inoltre con Code::Blocks non c'è neppure bisogno di inserirlo. Se proprio vuoi puoi optare per un 'getchar()'
- Non utilizzare variabili in più, meno variabili usi meglio è. Così facendo andando avanti, i programmi si faranno molti più grossi e avere molte variabili potrebbe rallentare ed appesantire la compilazione e l'esecuzione. Ovviamente, se richiesto usa le variabili richieste
- Indenta il tuo codice. Inserisci bene le graffe. Utilizza nomi di variabili corti (massimo 16 caratteri), che siano facili da ricordare,tutto minuscolo (almeno non devi ricordarti quale carattere è maiuscolo). Commenta il tuo codice con '//commento' (commento su linea singola) o '/*commento*/' (commento su più linee):
C:
int main()
{
  
if(/*condizione*/)
    {
        // istruzione
        // istruzione
    }
 
    if (/*condizione*/) {
        // istruzione
        // istruzione
    }

   if (/*condizione*/)
        // istruzione
/*Se dopo un if, un while o un for hai solo una riga di istruzione che fa riferimento al costrutto/ciclo precendente puoi evitare le parentesi tonde. */
 
    while (/*condizione*/)
    {
        // istruzione
        // istruzione
    }
 
    while (/*condizione*/) {
        // istruzione
        // istruzione
    }
 
    for (/*condizione*/)
    {
        // istruzione
        // istruzione
    }
 
    do
    {
     
    } while (/*condizione*/);


    return 0;
}
C:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n1,n2,n3; // Dichiaro le mie variabili
   
    // Acquisisco i 3 valori interi
    printf("Inserisci il primo numero: ");
    scanf("%d",&n1);

    printf("Inserisci il secondo numero: ");
    scanf("%d",&n2);

    printf("Inserisci il terzo numero: ");
    scanf("%d",&n3);

    if ((n1*n2) == n3) // Verifico se il risultato della la moltiplicazione tra i primi due numeri sia uguale al terzo numero
        printf("\nIl risultato di %d*%d e' uguale a %d\n",n1,n2,n3);
    else
        printf("\nIl risultato di %d*%d non e' uguale a %d\n",n1,n2,n3);

    return 0;
}
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,946
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
In ambito scolastico, quindi a solo scopo di studio, il DevC/C++ si può usare, purché si prenda la precauzione di scaricare la versione relativamente aggiornata chiamata Orwell DevC++ (datata Gennaio 2015).
https://sourceforge.net/projects/orwelldevcpp/
https://orwelldevcpp.blogspot.com
Dev/Orwell è solo un IDE (ambiente di sviluppo, molto semplice in questo caso) non un compilatore;
il compilatore vero e proprio è il TDM GCC v4.9.2 ossia lo stesso che è integrato nella versione pronta all'uso di Code::Blocks, il che significa che, comodità e raffinatezza dell'IDE a parte, i risultati di compilazione sono identici e dipendono solo da quanto "bene" si programma.
Sfortunatamente la maggior parte degli insegnanti delle superiori non sono informatici, meglio attenersi a quanto ti dicono di fare per evitare votacci (a parte l'orribile System.pause() perché basta usare un'istruzione di lettura fitizia per fermare l'esecuzione).

Di fatto sono d'accordo con tutto quanto avete scritto,
aborrite il non-standard System.pause() e, quando si vuole qualcosa di più serio, sotto Windows si può usare Visual Studio Community Edition, identico alla versione Professional in tutto e per tutto, gratuito sia per i privati che ad uso professionale per aziende fino a 50 dipendenti.

Per fare un confronto tra numeri in virgola mobile bisogna evitare l'operatore di uguaglianza (non solo in C/C++, ma in tutti i linguaggi);
occorre definire un "errore" piccolo a sufficienza e vedere se il risultato cade intorno a quanto ci si aspetta; per esempio se vuoi controllare che un risultato è uguale a 100 devi verificare che sia compreso in un intervallo "ragionevole" intorno a 100 ossia
risultato>=100-errore e risultato<=100+errore
se definisci errore=0.0000001 (un decimilionesimo) il tuo risultato sarà "uguale" a 100 quando
risultato>=99.9999999 e risultato<=100.0000001
 
Ultima modifica:

movlw

Nuovo Utente
32
6
CPU
AMD A4 5300
Dissipatore
Default
Scheda Madre
AsRock DG3+
HDD
Toshiba 500GB
RAM
Kingstone 8GB DDR3
GPU
APU HD7480D
Monitor
Benq FP71G+
PSU
ITEK
OS
Windows 10 64bit
Per fare un confrono tra numeri in virgola mobile bisogna evitare l'operatore di uguaglianza (non solo in C/C++, ma in tutti i linguaggi);
occorre definire un "errore" piccolo a sufficienza e vedere se il risultato cade intorno a quanto ci si aspetta; per esempio se vuoi controllare che un risultato è uguale a 100 devi verificare che sia compreso in un intervallo "ragionevole" intorno a 100 ossia
risultato>=100-errore e risultato<=100+errore
se definisci errore=0.0000001 (un decimilionesimo) il tuo risultato sarà "uguale" a 100 quando
risultato>=99.9999999 e risultato<=100.0000001
Esattamente. Si fa la differenza tra i valori da confrontare e si confronta la differenza ottenuta con il margine di errore scelto, che spesso coincide con FLT_EPSILON contenuto in <float.h>.
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili