czosnek17 Temat założony przez niniejszego użytkownika |
Lekcja 21 sprawdzanie liczb » 2012-03-17 19:37:01 Program ma losować liczby i zapisać 5 niepowtarzających się. #include <iostream> #include <cstdlib> #include <ctime> using namespace std;
int wylosuj() { return( rand() % 10 ) + 1; }
bool sprawdz( int zapisz[], int los, int lwylos ) { int licz = 0; do { licz++; cout << "licznik" << licz << endl; cout << "liczby wczesniej zapisane" << zapisz[ licz ] << endl; if( zapisz[ licz ] != los ) return true; } while( licz != lwylos ); return false; }
int main() { srand( time( 0 ) ); int zapisz[ 6 ]; int lwylos = 0; do { int los = wylosuj(); cout << "los=" << los << endl; bool spr = sprawdz( zapisz, los, lwylos ); cout << "spr " << spr << endl; if( spr == true ) { lwylos++; zapisz[ lwylos ] = los; } } while( lwylos != 5 ); int zxc = 0; cout << "liczby:" << endl; do { zxc++; cout << zapisz[ zxc ] << std::endl; } while( zxc < 5 ); return 0; }
Problem: zapisz[ licz ] w funkcji sprawdzającej prawie za każdym zapętleniem jest równe pierwszej wylosowanej liczbie, bo licznik w tej funkcji=1 W efekcie if( zapisz[ licz ] != los ) return true; za każdym razem zwraca prawdę, a program zapisuje powtarzające się liczby. |
|
jsc |
» 2012-03-17 20:06:53 Błąd leży w kodzie: if( zapisz[ licz ] != los ) return true;
}
W dla zapisz [] = {3, 1} i los 1 zrobi coś takiego: sprawdź czy 3 (początkowa wartość wyrażenia zapisz[ licz ] na początku wykonywania algorytmu) != 1, jeśli tak zwróć true i zwróć sterowanie do miejsca wywołania funkcji. Jak widzisz sprawdzenie drugiej komórki jest pominięte, więc nie ma się dziwić, że dostaniesz: zapisz [] = {3, 1, 1} |
|
czosnek17 Temat założony przez niniejszego użytkownika |
» 2012-03-17 20:26:33 Nie wiem czy dobrze zrozumiałem to, co napisałeś. Jak można by zmienić ten kod, żeby dział poprawnie? Zrobiłem coś niezgodnego z tym? http://cpp0x.pl/kursy/Kurs-C++/Poziom-2/Funkcje-a-slowo-kluczowe-return/339 |
|
jsc |
» 2012-03-17 20:34:27 Ty sprawdziłeś tylko część tablicy czy jest prawidłowa. Aby było dobrze musisz opóźnić return true; do sprawdzenia jej całości.
Proponuję albo zmienić warunek, albo użycie lokalnej zmiennej logicznej, którą na końcu funkcji można return nazwaZmiennej; |
|
czosnek17 Temat założony przez niniejszego użytkownika |
» 2012-03-18 19:01:44 Jeszcze raz przeanalizowałem program. Sprawdzam tylko tą część tablicy, która ma już przypisane wylosowane liczby. Jak bym już na początku programu sprawdzał całą tablicę, zostałyby w niej zapisane liczby, które nie zostały wylosowane np 249324 itd. Dlaczego przy każdym powtórzeniu pętli cout << "liczby wczesniej zapisane" << zapisz[ licz ] << endl; jest pierwszą zapisaną liczbą? Jakby inkrementacja nie działała. |
|
jsc |
» 2012-03-18 19:17:51 Bo za pierwszym iteracją testu zaszedł warunek wyjścia z funkcji z wynikiem true. |
|
czosnek17 Temat założony przez niniejszego użytkownika |
» 2012-03-18 20:02:20 Teraz funkcja wygląda tak: bool sprawdz( int zapisz[], int los, int lwylos ) { bool zm; int licz = 0; do { licz++; cout << "licznik" << licz << endl; cout << "liczby wczesniej zapisane" << zapisz[ licz ] << endl; if( zapisz[ licz ] != los ) { zm = 1; } else zm = 0; } while( licz != lwylos ); return zm; }
Licznik na początku programu ma 2983 na końcu 3130 i błąd aplikacji. Co znowu!? |
|
jsc |
» 2012-03-18 20:04:21 I znowu błąd.
Funkcja dostaje wynik testu z ostatniej iteracji. |
|
« 1 » 2 3 |