|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Esercizio C++
Salve a tutti, mi sto esercitando con alcuni esercizi proposti da un libro per un esame di C++, dato che non ho trovato un thread ufficiale di questo linguaggio di programmazione vi chiedo qualche aiuto da qui.
Ho appena finito di leggere la teoria e sto cominciando a cimentarmi con un po' di esercizi. In questo esercizio devo leggere un numero intero da tastiera e determinare se si tratta di un numero perfetto. Questo è quello che sono riuscito a combinare fino ad ora Codice:
#include <iostream> #include <math.h> using namespace std; bool perf (int a) { int i=1; double p; vero: return true; while (i==a) { p = pow(2,i)*(pow(2,(i+1))-1); if (p==a) goto vero; break; i++; } } int main () { int n; bool v; cout << "Inserire un numero intero: "; cin >> n; v = perf(n); if (v == true) cout << "Il numero " << n << " e' un numero perfetto!\n"; if (v == false) cout << "Il numero " << n << " NON e' un numero perfetto\n"; system ("pause"); return 0; } Il programma restituisce come output "Il numero n e' un numero perfetto!" anche se questo non lo è. Quali errori logici e di programmazione ho fatto? |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
In primo luogo direi che il break nel ciclo while della funzione perf è nel posto sbagliato, oltre ad essere superfluo: in assenza di graffe non si trova nello scope dell'if, ma in quello del while, quindi interrompe incondizionatamente l'esecuzione al primo ciclo (se non si avvera l'if con relativo goto).
La sua necessità poi mi risulta nulla, visto che a causa del goto l'esecuzione si sposta definitivamente alla relativa flag, quindi anche se lo scope fosse definito non mi risulta che quel break possa esser mai eseguito. Cosa ritorna la funzione perf se p non è mai uguale ad a? La risposta non mi risulta esista, immagino sia un caso indefinito (ora non ho rintracciato un documento semi-ufficiale che lo contenga...). In pratica credo che il valore sarà quello già presente nella zona di memoria dove il main va a cercare il risultato, quindi o vero o falso, potenzialmente anche in modo consistente a seconda dello stato dei registri della CPU in quel punto dell'esecuzione. Solitamente errori di questo tipo possono essere segnalati dal compilatore come warning se è presente almeno un return, errori se non ce n'è nessuno. Ultimo appunto: quel goto è veramente, veramente superfluo, come nel 99.99% dei casi in cui ti potrà venir in mente di usare un goto. Concludendo: un bel return con valore statico alla fine ed un altro all'interno del while al posto del goto.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: May 2009
Messaggi: 186
|
Non importa. La funzione perf ritorna sempre true visto che la terza riga è un bel "return true;". Nel while neanche ci entra e il compilatore sicuramente segnala qualche warning...
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Hai proprio ragione ESSE-EFFE, non ho notato questo trascurabile dettaglio!
![]() Ok, lo ammetto, non ho mai usato un goto nella mia carriera di programmatore, ma ho trovato un paio di casi (il famoso 0.01% di cui sopra) in cui erano troppo geniali per non ammirarne la grazia.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Innanzitutto grazie per le risposte
![]() Allora in effetti il goto l'ho utilizzato come ultima spiaggia a causa del fatto che il programma non funzionava correttamente. Dunque ho levato il break e ho risistemato un po' la funzione, introducendo una nuova variabile bool e inizializzandola come false, poi parte il ciclo che, se soddisfa la condizione a == p cambia la variabile in true, e infine un bel return w Codice:
bool perf (int a) { bool w = false; int i=1; double p; while (i==a) { p = pow(2,i)*(pow(2,(i+1))-1); if (p==a) w = true; i++; } return w; } |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Meglio, ora il primo problema è la condizione del while: se, per esempio, a = 6 ed i = 1, quante volte eseguirà il ciclo mentre i == a?
Indizi sulle condizioni da impostare:
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Quote:
Se p==a non è necessario continuare perché il numero verifica la condizione, per cui il ciclo dovrebbe finire, Ecco perché avevo messo quel break |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Ho fatto un altro esercizio analogo, dove mi chiede di trovare se il numero è primo (divisibile solo per 1 e per se stesso) e pare che funzioni
![]() Codice:
#include <iostream> using namespace std; bool primo (int p) { bool f=true; for (int i=2; i<p; i++) { int q; q = p%i; if (q==0) f = false; } return f; } int main () { int a; bool g; cout << "Scrivere un numero intero positivo: "; cin >> a; if (a<0 || a==0) { cerr << "Il numero deve essere intero positivo.\n"; return 0; } else { g = primo (a); if (g==true) cout << "Il numero " << a << " e' un numero primo!\n"; if (g==false) cout << "Il numero " << a << " NON e' un numero primo\n"; } system ("pause"); return 0; } |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Oct 2004
Messaggi: 1945
|
te l'hanno già detto perchè non va l'altro esercizio
cambia Codice:
while(i == a) Codice:
while(i < a) Codice:
while (i < a) { p = pow(2,i)*(pow(2,(i+1))-1); if (p==a) return true; i++; } Codice:
if (q==0) return false; |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Ah ecco, non avevo capito il fatto del while
![]() ![]() |
![]() |
![]() |
![]() |
#11 |
Member
Iscritto dal: May 2009
Messaggi: 186
|
Sei sicuro? Prova con 120...
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Occorre aggiungere una condizione.
Questa breve enunciazione del teorema di Euclide-Eulero evidenzia ciò che manca: ogni numero perfetto pari è della forma 2ⁿ⁻¹ * ( 2ⁿ - 1 ), ove il numero tra parentesi è un numero, detto di Mersenne, primo. Quindi ti torna utile la funzione che testa numeri primi che hai postato... P.S. non star lì a guardare gli esponenti, il tuo calcolo con i pow è corretto per quel test: prendi il pezzo della formula, pensa che variabile è per te l'n ed aggiungi un test prima di dichiarare vero il bool/ritornare true.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Aug 2006
Città: Monaco di Baviera
Messaggi: 3233
|
Ok perfetto, grazie mille
![]() Oggi mi sto cimentando con gli array, in particolare devo realizzare un programma che immagazzini n elementi in un vettore e stabilisca se esso è maggioritario, ovvero se contiene almeno 1 elemento che appare nel vettore n/2 volte Codice:
#include <iostream> using namespace std; void leggi (int vett[], int n) { for (int i=0; i<n; i++) { cout << "Elemento " << (i+1) << " di " << n << " : "; cin >> vett[i]; } } bool mag (int vett[], int n) { int m; for (int i=0; i<n; i++) { for (int k=0; k<n; k++) { if (vett[i]==vett[k]) m++; } if ( m > (n/2) ) return true; } return false; } int main () { int n; bool v; cout << "Di quanti elementi e' composto il vettore?: "; cin >> n; int a[n]; leggi (a,n); v = mag (a,n); if (v==true) cout << "Il vettore e' maggioritario!\n"; if (v==false) cout << "Il vettore NON e' maggioritario\n"; system ("pause"); return 0; } ![]() Ultima modifica di morpheus89 : 24-08-2011 alle 11:26. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:06.