Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - aiuto perfavore non riesco a capire perché questa funzione non funziona come voglio.
Forum - C/C++ - aiuto perfavore non riesco a capire perché questa funzione non funziona come voglio.

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Milton (Normal User)
Newbie


Messaggi: 1
Iscritto: 03/11/2020

Segnala al moderatore
Postato alle 15:35
Martedì, 03/11/2020
#include <stdio.h>

//prototipi dei nostri sottoprogrammi (funzioni) dico cosa faccio
int menu();
int Calcolo_Coppie_Uguale();
int Calcola_Coppie_Divisibili();

int main()
{                        //inizio la seconda funzione del menu(aggiunto da me)
    int sceltaMain;
    sceltaMain=menu();  //chiamo la funzione menu che restituisce la scelta
    if(sceltaMain==1){
        int risultato=Calcolo_Coppie_Uguale();
        printf("Il numero di coppie uguali è %d\n",risultato);
    }
    else if(sceltaMain==2){
        int risultato=Calcola_Coppie_Divisibili();
        printf("Il numero di coppie Divisibili è %d\n",risultato);
        
    }
    else{
        //stampare un messaggio di errore
    }
        

    return 0;
}
//definisco come fanno le cose i prototipi

//funzione che restituisce la scelta fatta dall'utente
int menu(){
    int scelta; //locale al menu
    printf("Quale operazione vuoi eseguire?\n");
    printf("Inserisci 1 per coppie uguali consecutive\n");
    printf("Inserisci 2 per coppie divisibili consecutive\n");
    scanf("%d",&scelta);
    return scelta;
}

//acquisiti i numeri restituisce il numero di coppie consecutive uguali
int Calcolo_Coppie_Uguale(){
    int contatore; //variabile locale a questo sottoprogramma
    int numCorrente;
    int numPrecedente;
    contatore=0;
    printf("Comincia ad inserire i numeri (0 termina inserimento)!!\n");
    scanf("%d",&numCorrente);
    numPrecedente=0;
    while(numCorrente>0){
        if(numCorrente==numPrecedente){
            contatore++;
        }
        numPrecedente=numCorrente;
        printf("Inserisci un nuovo numero (zero per terminare)\n");
        scanf("%d",&numCorrente);
        
    }
    return contatore;
}

//acquisiti i numeri restituisce il numero di cppie consecutive divisibili
int Calcola_Coppie_Divisibili(){
    int contatore; //variabile locale a questo sottoprogramma
    int numCorrente;
    int numPrecedente;
    contatore=0;
    printf("comincia ad inserire i numeri (0 termina inserimento)!!\n");
    scanf("%d",&numCorrente);
    numPrecedente=0;
    while(numCorrente>0);{
        if(numCorrente%numPrecedente==0){
            contatore++;
        }
     numPrecedente=numCorrente;
        printf("Inserisci un nuovo numero (zero per terminare)\n");
        scanf("%d",&numCorrente);
    }
    return contatore;
}




// non capisco perchè la seconda funzione non funziona :(

PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 577
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 21:02
Martedì, 03/11/2020
Ti è scappato un punto e virgola di troppo tra la parentesi chiusa e la graffa aperta. Quel punto e virgola dà luogo a un ciclo potenzialmente infinito (se il primo numero inserito è maggiore di 0).

Codice sorgente - presumibilmente Plain Text

  1. while(numCorrente>0);{ // l'errore è qui...
  2.     if(numCorrente%numPrecedente==0){
  3.         contatore++;
  4.     }
  5.     numPrecedente=numCorrente;
  6.     printf("Inserisci un nuovo numero (zero per terminare)\n");
  7.     scanf("%d",&numCorrente);
  8. }



Come potrebbe testimoniare qualsiasi parroco un minimo esperto, è certo che una funzione che non funziona è poco funzionale.

Ultima modifica effettuata da AldoBaldo il 03/11/2020 alle 21:05


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 767
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 21:35
Martedì, 03/11/2020
Oltre al punto e virgola che ti ha fatto notare AldoBaldo, non puoi scrivere: numPrecedente = 0
e poi farci una divisione anche se vuoi solo il resto: if(numCorrente % numPrecedente == 0)
Codice sorgente - presumibilmente C++

  1. int Calcola_Coppie_Divisibili(){
  2.     int contatore = 0; //variabile locale a questo sottoprogramma
  3.     int numCorrente = 0;
  4.     int numPrecedente = 1;
  5.     printf("comincia ad inserire i numeri (0 termina inserimento)!!\n");
  6.     scanf("%d",&numCorrente);
  7.  
  8.     while(numCorrente>0){
  9.         if(numCorrente % numPrecedente == 0){
  10.               contatore++;
  11.         }
  12.         numPrecedente=numCorrente;
  13.         printf("Inserisci un nuovo numero (zero per terminare)\n");
  14.         scanf("%d",&numCorrente);
  15.     }
  16.     return contatore;
  17. }


Ultima modifica effettuata da Carlo il 03/11/2020 alle 21:36


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 577
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:07
Martedì, 03/11/2020
Vero! Non avevo fatto caso alla letale divisione per zero.

Basta aggiungere una controllo di condizione che assicuri che il numero precedente sia diverso da zero e in caso contrario eviti la divisione incriminata.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 767
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:44
Martedì, 03/11/2020
Ho fatto partire la variabile da 1, si poteva anche fare come dici tu:
Codice sorgente - presumibilmente C++

  1. int Calcola_Coppie_Divisibili(){
  2.     int contatore = 0; //variabile locale a questo sottoprogramma
  3.     int numCorrente = 0;
  4.     int numPrecedente = 0;
  5.     printf("comincia ad inserire i numeri (0 termina inserimento)!!\n");
  6.     scanf("%d",&numCorrente);
  7.  
  8.     while(numCorrente>0){
  9.         if(numPrecedente != 0 && numCorrente % numPrecedente == 0){
  10.               contatore++;
  11.         }
  12.         numPrecedente=numCorrente;
  13.         printf("Inserisci un nuovo numero (zero per terminare)\n");
  14.         scanf("%d",&numCorrente);
  15.     }
  16.     return contatore;
  17. }


&& salta il confronto successivo e ti mette al riparo dall'errore, ma la logica di conteggio è sbagliata, il risultato non è sempre correto, Milton ci deve lavorare un po'...:k:

Ultima modifica effettuata da Carlo il 03/11/2020 alle 22:53


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 577
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 16:58
Mercoledì, 04/11/2020
@Carlo

Direi che con il controllo numPrecedente!=0 il conteggio è corretto, perché...

riga 6. viene inserito numCorrente
riga 8. se numCorrente è <1 il ciclo while viene saltato integralmente
riga 9. arrivati qui, numPrecedente e' SICURAMENTE >=0, perché al primo ciclo è 0 per inizializzazione, mentre dopo è >0 essendo che la condizione viene controllata all'ingresso del while
riga 10. si entra in questo blocco solo a partire dal secondo ciclo (nel primo ciclo non c'è comunque nulla da confrontare, dato che si ha un solo numero e non si può fare alcuna divisione con %) e solo se il resto della divisione è 0
riga 12. numPrecedente riceve un valore che è SICURAMENTE >0

Vedi qualche falla? A me sembra tutto a posto.


Ultima modifica effettuata da AldoBaldo il 04/11/2020 alle 16:59


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 767
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 20:45
Mercoledì, 04/11/2020
@ AldoBaldo,
l'errore è nella logica, ti è sfuggito perché pensavi che chi ha scritto lo ha fatto logicamente, invece ha solo copiato e incollato il codice delle coppie, e cercato di faro funzionare con i divisibili. :nono:

Analisi coppie divisibili
    contatore = 0;
    numCorrente = 0;
    numPrecedente = 0;

inserisco il primo numero = 10
    contatore = 0;
    numCorrente = 10;
    numPrecedente = 0;

entro nel while e la condizione (numPrecedente != 0) è falsa si salta a
numPrecedente=numCorrente;
    contatore = 0;
    numCorrente = 10;
    numPrecedente = 10;

inserisco il secondo numero = 5
    contatore = 0;
    numCorrente = 5;
    numPrecedente = 10;

ritorno all'if (numPrecedente != 0) è vera, (numCorrente % numPrecedente == 0) è falsa perché 5 % 10 non da zero
contatore non si incrementa.

i numeri immessi sono 10 e 5, sono divisibili e contatore si doveva incrementare.

numCorrente % numPrecedente, sono invertiti, nel calcolo delle coppie consecutive è ininfluente, in una divisione no...

E' una diatriba tra noi perché Milton ha posto il quesito, ma non se ne interessa. :rotfl:

corretto:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2.  
  3. //prototipi dei nostri sottoprogrammi (funzioni) dico cosa faccio
  4. int menu();
  5. int Calcolo_Coppie_Uguale();
  6. int Calcola_Coppie_Divisibili();
  7.  
  8. int main()
  9. {                       //inizio la seconda funzione del menu(aggiunto da me)
  10.     int sceltaMain;
  11.     sceltaMain=menu();  //chiamo la funzione menu che restituisce la scelta
  12.     if(sceltaMain==1){
  13.         int risultato=Calcolo_Coppie_Uguale();
  14.         printf("Il numero di coppie uguali sono %d\n",risultato);
  15.     }
  16.     else if(sceltaMain==2){
  17.         int risultato=Calcola_Coppie_Divisibili();
  18.         printf("Il numero di coppie Divisibili sono %d\n",risultato);
  19.     }
  20.     else{
  21.         //stampare un messaggio di errore
  22.     }
  23.     return 0;
  24. }
  25. //definisco come fanno le cose i prototipi
  26.  
  27. //funzione che restituisce la scelta fatta dall'utente
  28. int menu(){
  29.     int scelta; //locale al menu
  30.     printf("Quale operazione vuoi eseguire?\n");
  31.     printf("Inserisci 1 per coppie uguali consecutive\n");
  32.     printf("Inserisci 2 per coppie divisibili consecutive\n");
  33.     scanf("%d",&scelta);
  34.     return scelta;
  35. }
  36.  
  37. //acquisiti i numeri restituisce il numero di coppie consecutive uguali
  38. int Calcolo_Coppie_Uguale(){
  39.     int contatore = 0; //variabile locale a questo sottoprogramma
  40.     int numCorrente = 0;
  41.     int numPrecedente = 0;
  42.     contatore=0;
  43.     printf("Comincia ad inserire i numeri (0 termina inserimento)!!\n");
  44.     scanf("%d",&numCorrente);
  45.     numPrecedente=0;
  46.     while(numCorrente>0){
  47.         if(numCorrente==numPrecedente){
  48.             contatore++;
  49.         }
  50.         numPrecedente=numCorrente;
  51.         printf("Inserisci un nuovo numero (zero per terminare)\n");
  52.         scanf("%d",&numCorrente);
  53.     }
  54.     return contatore;
  55. }
  56.  
  57. //acquisiti i numeri restituisce il numero di cppie consecutive divisibili
  58.  
  59. int Calcola_Coppie_Divisibili(){
  60.     int contatore = 0; //variabile locale a questo sottoprogramma
  61.     int numCorrente = 0;
  62.     int numPrecedente = 0;
  63.     printf("comincia ad inserire i numeri (0 termina inserimento)!!\n");
  64.     scanf("%d",&numCorrente);
  65.  
  66.     while(numCorrente>0){
  67.         if(numPrecedente != 0 && numPrecedente % numCorrente == 0){
  68.               contatore++;
  69.         }
  70.         numPrecedente=numCorrente;
  71.         printf("Inserisci un nuovo numero (zero per terminare)\n");
  72.         scanf("%d",&numCorrente);
  73.     }
  74.     return contatore;
  75. }



Ultima modifica effettuata da Carlo il 04/11/2020 alle 21:43


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 577
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:01
Mercoledì, 04/11/2020
Macché diatriba! E' che a me piace questo tipo di confronto, ci sguazzo come una carpa in una risaia.

Ho capito il punto, che avevo notato, ma non lo considero un errore di logica, ovvero considero che quando il numero precedente è 10 e quello corrente è 5, in effetti il contatore non deve essere aumentato, proprio perché 5 non è divisibile per 10. Cioè, considero parte delle "specifiche" (capirai...) richieste il fatto che sia l'ultimo numero inserito ad essere divisibile per quello precedente, e che il contrario non faccia parte delle richieste.

Invece, a quanto ho capito, secondo te dovrebbe essere verificata sia la divisibilità del numero precedente per quello corrente, sia la divisibilità del numero corrente per quello precedente. Si può fare senza neppure alzare un sopracciglio, ma... è poi quello che bisognerebbe fare secondo le "specifiche" dell'esercizio?

Codice sorgente - presumibilmente C++

  1. int Calcola_Coppie_Divisibili(){
  2.     int qDiv  = 0; // qDiv: quantita' dei divisori
  3.     int nCorr = 0; // nCorr: numero corrente
  4.     int nPrec = 0; // nPrec: numero precedente
  5.  
  6.     printf( "Inserisci il primo numero (zero per terminare): " );
  7.     scanf( "%d", &nCorr );
  8.  
  9.     while( nCorr>0 ){
  10.         if( nPrec ) qDiv += !(nPrec%nCorr)||!(nCorr%nPrec);
  11.  
  12.         nPrec = nCorr;
  13.  
  14.         printf( "Inserisci un nuovo numero (zero per terminare): " );
  15.         scanf( "%d", &nCorr );
  16.     }
  17.  
  18.     return qDiv;
  19. }



ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 767
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:34
Mercoledì, 04/11/2020
Testo quotato

Postato originariamente da AldoBaldo:
Invece, a quanto ho capito, secondo te dovrebbe essere verificata sia la divisibilità del numero precedente per quello corrente, sia la divisibilità del numero corrente per quello precedente. Si può fare senza neppure alzare un sopracciglio, ma... è poi quello che bisognerebbe fare secondo le "specifiche" dell'esercizio?



Il menu di scelta dice: "Inserisci 2 per coppie divisibili consecutive".

se inserisco 10 e poi 5 (esco con 0), la risposta è: "il numero di coppie divisibili è zero", intanto questo risultato è sbagliato.

Poi se vuoi interpretare che la divisibilità va controllata anche al contrario, io non ci avevo pensato, ma il menù di scelta non lo vieta e potresti avere ragione, ma comunque non confuta il fatto che il programma originale da risultati sbagliati.:D

Carino il sitema per incrementare qDiv :k:

Ultima modifica effettuata da Carlo il 04/11/2020 alle 22:37


in programmazione tutto è permesso
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo