Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Lekcja 21 sprawdzanie liczb

Ostatnio zmodyfikowano 2012-03-27 19:42
Autor Wiadomość
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ę.
C/C++
#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
C/C++
if( zapisz[ licz ] != los )
     return true;
 za każdym razem zwraca prawdę, a program zapisuje powtarzające się liczby.
P-52769
jsc
» 2012-03-17 20:06:53
Błąd leży w kodzie:
C/C++
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}
P-52770
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
P-52773
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;
P-52774
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.
P-52870
jsc
» 2012-03-18 19:17:51
Bo za pierwszym iteracją testu zaszedł warunek wyjścia z funkcji z wynikiem true.
P-52871
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-03-18 20:02:20
Teraz funkcja wygląda tak:
C/C++
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!?
P-52877
jsc
» 2012-03-18 20:04:21
I znowu błąd.

Funkcja dostaje wynik testu z ostatniej iteracji.
P-52878
« 1 » 2 3
  Strona 1 z 3 Następna strona