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

Pioziom 2 Rozdział 18

Ostatnio zmodyfikowano 2018-04-06 19:51
Autor Wiadomość
Pawełek
Temat założony przez niniejszego użytkownika
Pioziom 2 Rozdział 18
» 2018-04-05 14:34:46
Napisz program, który wylosuje 999 liczb całkowitych z zakresu od 4 do 10 włącznie, wypisze te wartości na ekran, po czym zsumuje je i wynik wypisze na ekran. Program ma wykorzystywać tablicę, która zostanie najpierw wypełniona liczbami losowymi z określonego przedziału, a następnie wynik zostanie obliczony na podstawie zawartości całej tablicy.

Mam problem z zsumowaniem wylosowanych liczb.
Co jest nie tak z tym programem?




C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int dodawanie( int nlicznik, int liczba[], int b )
{
   
    return b += liczba[ nlicznik ];
   
}

int losowanie()
{
    int a = rand() % 7 + 4;
    return a;
}
int main()
{
    srand( time( NULL ) );
    int licznik = 0;
    int liczba[ 1000 ];
    do
    {
        cout << licznik << " Losowanie: " << losowanie() << std::endl;
        liczba[ licznik ] = losowanie();
        licznik++;
    } while( licznik < 1000 );
   
    int nlicznik = 0;
    int b = liczba[ 0 ];
    do
    {
        cout << dodawanie( nlicznik, liczba, b ) << endl;
        nlicznik++;
       
    } while( nlicznik < 1000 );
   
    return 0;
}
P-170467
Luq
» 2018-04-05 15:27:44
return b += liczba[ nlicznik ];

To działanie modyfikuje tylko zmienną lokalną w funkcji i nie ma wpływu na zmienną w mainie. Zresztą robienie tego funkcją jest zbędne, po prostu w pętli do {...} while wpisz b += liczba[nLicznik]. I wynik wypisuj poza pętlą.
P-170469
Pawełek
Temat założony przez niniejszego użytkownika
» 2018-04-05 17:08:45
dzięki, zrobiłem tak jak napisałeś

W rozdziale 19 to samo zadanie należy zrobić tylko i wyłącznie za pomocą funkcji.. znowu mam problem z sumowaniem całości :/

C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int dodawanie( int licznik, int liczba[], int b )
{
    do
    {
       
       
        b += liczba[ licznik ];
        licznik++;
    } while( licznik < 1000 );
   
    return b;
   
}

int losowanie( int a, int liczba[], int licznik )
{
   
    do
    {
        int a = rand() % 7 + 4;
        cout << licznik << " Losowanie: " << a << std::endl;
        liczba[ licznik ] = a;
        licznik++;
    } while( licznik < 1000 );
   
    return 0;
}
int main()
{
    srand( time( NULL ) );
    int licznik = 0;
    int liczba[ 1000 ];
    int b = liczba[ 0 ];
    int a;
    losowanie( a, liczba, licznik );
    int suma = dodawanie( licznik, liczba, b );
    cout << "Suma: " << suma;
   
   
   
    return 0;
}

Nie rozumiem dlaczego mi to nie sumuje wszystkich liczb, przecież jeśli funkcja nie zwraca wartości do mainu a zmienia wartość zmiennej jedynie 'lokalnie' to zrobienie tego za pomocą funkcji jest niemożliwe.
P-170471
jankowalski25
» 2018-04-05 18:51:01
Po pierwsze: włącz ostrzeżenia kompilatora.
Po drugie: debuguj!

int b = liczba[ 0 ];
Dlaczego kopiujesz jakieś śmieci z jednej zmiennej do drugiej?

losowanie( a, liczba, licznik );
Jaką wartość ma tutaj zmienna a?

C/C++
int losowanie( int a, int liczba[], int licznik )
{
    do
    {
        int a = rand() % 7 + 4;
        //...
Dlaczego w funkcji losowanie() zasłaniasz argument tworząc nową zmienną lokalną o nazwie a?

C/C++
int losowanie( int a, int liczba[], int licznik )
{
    //...
    return 0;
}
Dlaczego funkcja losowanie() zwraca zawsze zero?

przecież jeśli funkcja nie zwraca wartości do mainu a zmienia wartość zmiennej jedynie 'lokalnie' to zrobienie tego za pomocą funkcji jest niemożliwe
Jest możliwe, chociażby poprzez referencję. Wydaje mi się jednak, że na tym etapie możliwość zmiany danych wewnątrz tablic oraz zwracanie sensownych wartości z funkcji powinno w zupełności wystarczyć.
P-170475
Luq
» 2018-04-05 18:53:21
A po co te parametry licznik i b w funkcji od sumowania? Żeby sumować elementy tablicy trzeba przekazać do funkcji tablicę i ewentualnie jej rozmiar (akurat u ciebie jest zakodowany na stałe na wartość 1000, więc można się obejść bez tego parametru). Więc funkcja powinna przyjmować nie więcej niż te dwa parametry. Podobnie jest z funkcją losowanie.

PS. Zmienną do sumowania inicjalizuj na 0, nie na pierwszy element tablicy.
P-170476
Pawełek
Temat założony przez niniejszego użytkownika
» 2018-04-05 19:13:22
int b = liczba[ 0 ];
Dlaczego kopiujesz jakieś śmieci z jednej zmiennej do drugiej?

Jest to ustalenie pierwszej wartości zmiennej, tzn. przy wzorze
b += liczba[ licznik ];
 'b' ma u mnie wartość pierwszego elementu z tablicy 'liczba' nastepnie dzięki pętli powinna dodawać za każdym razem każdy kolejny element aż do 999 elementu.

losowanie( a, liczba, licznik );
Jaką wartość ma tutaj zmienna a?

Nie ma wartości, Ma za zadanie tylko wypisać wylosowaną wartość na ekranie, a poza tym jest bezużyteczna.

C/C++
C / C++
int losowanie( int a, int liczba[], int licznik )
{
    do
    {
        int a = rand() % 7 + 4;
        //...   
Dlaczego w funkcji losowanie() zasłaniasz argument tworząc nową zmienną lokalną o nazwie a?

Mój błąd, poprawiłem to już ale nic to nie zmieniło :(

C/C++
C / C++
int losowanie( int a, int liczba[], int licznik )
{
    //...
    return 0;
}
Dlaczego funkcja losowanie() zwraca zawsze zero?

Pierwotnie ta funkcja służyła mi tylko do wypisania liczb na ekranie, zmieniłem jednak teraz na zwracanie tablicy (Jeśli zwracanie tablicy jest w ogóle możliwe bo szczerze mówiąc to niewiem)
return liczba[ 1000 ];
 jednak na nic się to zdało, dalej nie sumuje mi całości.
P-170477
Pawełek
Temat założony przez niniejszego użytkownika
» 2018-04-05 19:19:20
A po co te parametry licznik i b w funkcji od sumowania? Żeby sumować elementy tablicy trzeba przekazać do funkcji tablicę i ewentualnie jej rozmiar (akurat u ciebie jest zakodowany na stałe na wartość 1000, więc można się obejść bez tego parametru). Więc funkcja powinna przyjmować nie więcej niż te dwa parametry. Podobnie jest z funkcją losowanie.

PS. Zmienną do sumowania inicjalizuj na 0, nie na pierwszy element tablicy.

Czyli jak miało by to wyglądąć? Kompletnie tego nie rozumiem
P-170478
jankowalski25
» 2018-04-05 20:24:15
Jest to ustalenie pierwszej wartości zmiennej, tzn. przy wzorze
b += liczba[ licznik ];
 'b' ma u mnie wartość pierwszego elementu z tablicy 'liczba' nastepnie dzięki pętli powinna dodawać za każdym razem każdy kolejny element aż do 999 elementu.
Nie, nie, nie. Tak to nie działa.
C/C++
int a = 2;
int b = a + 2; //b wynosi 4
a = 5;
std::cout << b; //b nadal wynosi 4, nie 7
Przecież w linijce
int b = liczba[ 0 ];
 wartość pierwszego elementu tablicy liczba zawiera śmieci. Instrukcje są wykonywane po kolei, jedna po drugiej. Wartości zmiennych są obliczane od razu (ewaluacja gorliwa), a nie dopiero wtedy, gdy są potrzebne (ewaluacja leniwa). Do ewaluacji leniwej należy używać funkcji, w każdym innym przypadku wartości podlegają ewaluacji gorliwej, czyli nie zostaną później zaktualizowane, dopóki jawnie tego nie napiszesz.

Nie ma wartości
Musi mieć. Pisząc
int a;
 sprawiasz, że zmienna a zawiera niezdefiniowaną wartość. Najlepiej od razu nadawać zmiennym wartości początkowe. Ewentualnie możesz zrobić to później, byleby zapis nastąpił przed pierwszym odczytem, inaczej zachowanie jest niezdefiniowane.

zmieniłem jednak teraz na zwracanie tablicy (Jeśli zwracanie tablicy jest w ogóle możliwe bo szczerze mówiąc to niewiem)
Jest możliwe, ale najpierw dobrze byłoby wiedzieć, po co chcesz zwrócić tablicę, skoro ten typ danych nie jest kopiowany, dopóki jawnie tego nie napiszesz (czyli cały czas działasz na oryginalnej tablicy, a nie na jej kopii).

return liczba[ 1000 ];
Nie, to tak nie działa. W ten sposób próbujesz uzyskać 1001 (indeksowanie zaczyna się od zera) element tablicy, który jest poza zakresem, co oznacza niezdefiniowane zachowanie.

Czyli jak miało by to wyglądąć?
Zacznij od włączenia ostrzeżeń kompilatora i popraw kod tak, aby ich nie było. Następnie włącz debugger i zacznij wykonywać całość linijka po linijce oraz podglądać wartości zmiennych, aby łatwiej namierzać błędy.
P-170479
« 1 » 2
  Strona 1 z 2 Następna strona