• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dla odmiany dzisiaj chcę się pochwalić samodzielnie zrobionym programem.

Object Storage Arubacloud
+2 głosów
287 wizyt
pytanie zadane 6 listopada 2020 w C i C++ przez rain.deer Początkujący (430 p.)

Cześć, po kilku postach, w których pytałam o sposób rozwiązania błędów w swoich kodach, chciałabym się dziś pochwalić krótkim, samodzielnie (tzn. z wykorzystaniem elementów z wcześniejszych kodów i lekcji) napisanym programikiem, który jak mi się wydaje działa dobrze. smiley Zadanie było następujące: 

"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."

#include <iostream>
#include <ctime>
#include <cstdlib>

int main()
{
    int liczba[999];
    int licznik = 0;
    std::srand(time(NULL));
    do
    {
       liczba[licznik] = (rand() % 7) + 4;
        licznik++;
    } while (licznik < 999);

    std::cout << "Podales nastepujace liczby: ";
    licznik = 0;
    do
    {
        std::cout << liczba[licznik] << ", ";
        licznik++;
    } while (licznik < 999);
    unsigned long long suma = liczba[0];
      suma = suma + liczba[licznik++];
        std::cout << "Suma wylosowanych liczb to " << suma << std::endl;

    return 0;
}

 

1
komentarz 7 listopada 2020 przez VBService Ekspert (253,120 p.)

wink

#include <iostream>
#include <ctime>
#include <cstdlib>
 
int main()
{
    int liczba[999];
    std::srand(time(NULL));
    for (int i=0; i<999; ++i) {
        liczba[i] = (rand() % 7) + 4;
    }
 
    std::cout << "Wylosowano nastepujace liczby:\n";
    unsigned long suma = 0;
    
    for (int i=0; i<999; ++i) {
        if (i % 20 == 0)  std::cout << "\n";
        std::cout << liczba[i] << ", ";
        suma += liczba[i];
    }
    
    std::cout << "\n\nSuma wylosowanych liczb to " << suma << std::endl;
 
    return 0;
}

 

komentarz 7 listopada 2020 przez rain.deer Początkujący (430 p.)

Z pewnością tak to należało zrobić, ale.. otrzymywanie gotowców nie pomaga w nauce. sad Ale dziękuję za ten fragment z "suma += liczba[i]", którego nie znałam. Moim sposobem pierwsza z wylosowanych liczb była sumowana 2 razy i fałszowało to wynik. A nie wiedziałam, jak to poprawnie zapisać. smiley

2 odpowiedzi

+1 głos
odpowiedź 7 listopada 2020 przez TOM_CPP Pasjonat (22,640 p.)
edycja 7 listopada 2020 przez TOM_CPP

Można napisać to bez użycia tablic i z wykorzystaniem biblioteki random. (C++ 11)

#include <iostream>
#include <random>
#include <iomanip>

using namespace std;

int main()
{
    mt19937 gen(random_device{}());
    uniform_int_distribution<> distrib(4,10);

    cout << "Wylosowano nastepujace liczby:" << endl;

    size_t suma {0};
    for( auto i {0} ; i<999 ; ++i )
    {
        if( i%30 == 0 ) cout << endl;
        cout << setw(2) << [&suma]( int number ){ suma += number; return number; }(distrib(gen)) << ' ';
    }

    cout << endl << endl << "Suma wylosowanych liczb to " << suma << endl;

	return 0;
}

 

komentarz 7 listopada 2020 przez NewEraOfPeace Gaduła (4,790 p.)

lambda nie musi być tu przypadkiem oznaczona jako mutable ?

komentarz 7 listopada 2020 przez TOM_CPP Pasjonat (22,640 p.)

Nie.

Słowo mutable odnosi się obiektów przechwyconych za pomocą [=] , tzn. obiektów kopiowanych (przekazywanych przez wartość). W takim przypadku mogą one być modyfikowane, oraz można przy ich pomocy wywoływać nie stałe funkcje składowe (jeżeli takie posiadają).

Przykład

#include <iostream>

using namespace std;

struct Foo
{
    void print(){ cout << "non const Foo" << endl; }
    void print_c() const { cout << "const Foo" << endl; }
};

int main()
{
    Foo foo;

    [=](){ foo.print_c(); }();
    [=]() mutable { foo.print(); }();
    [=]() { foo.print(); }(); // !!! does not compile !!!

	return 0;
}

 

komentarz 7 listopada 2020 przez rain.deer Początkujący (430 p.)

@TOM_CPP, jeszcze nie znam takich rzeczy, które użyłeś w swoim kodzie. Uczę się dopiero od miesiąca. sad A w treści zadania był wymóg zastosowania tablic, bo o tym była lekcja.

komentarz 7 listopada 2020 przez tkz Nałogowiec (42,000 p.)
edycja 7 listopada 2020 przez tkz

@TOM_CPP, Globalna przestrzeń nazw bije po oczach. Poza tym kod nie jest zgodny z c++11, a 17 i w górę. W pętli auto i {0} jest listą inicjalizującą.  

#include <iostream>
#include <random>
#include <iomanip>
  
int main()
{
    using std::cout, std::endl, std::setw, std::mt19937, std::uniform_int_distribution, std::random_device;
    auto gen = mt19937(random_device{}());
    auto distrib = uniform_int_distribution(4,10);
  
    cout << "Wylosowano nastepujace liczby:" << endl;
  
    size_t suma {0};
    for( auto i {0}, upperBound{999}; i < upperBound ; ++i )
    {
        if(const auto numberOfNumbersInOneLine {30}; i%numberOfNumbersInOneLine == 0 ) 
        {
            cout << endl;
        }
        cout << setw(2) << [&suma]( int number ){ suma += number; return number; }(distrib(gen)) << ' ';
    }
  
    cout << endl << endl << "Suma wylosowanych liczb to " << suma << endl;
}

Lambda też wydaje mi się zbędna.

komentarz 8 listopada 2020 przez TOM_CPP Pasjonat (22,640 p.)

@rain.deer,
Tak wiem, przykład pokazuje, że zadanie tego typu można napisać bez używania tablic, które w zależności od swojego rozmiaru, mogą zajmować dużo miejsca w pamięci.

komentarz 8 listopada 2020 przez TOM_CPP Pasjonat (22,640 p.)

@tkz,  

Kod jest zgodny z standardem C++11 zobacz  , natomiast Twój przykład już nie: zobacz

Zmienna zdefiniowana za pomocą auto i {0}; nie jest listą inicjalizującą  przykład

 

 

komentarz 8 listopada 2020 przez tkz Nałogowiec (42,000 p.)

@TOM_CPP,

cpp.sh/3psry 

Wiem, że mój kod nie jest zgodny z standardem 11. Dlatego też o tym nie wspominałem. Dopiero w standardzie 17 zmieniono postrzeganie auto foo{1}; z listy na int'a. 

https://dsp.krzaq.cc/post/1417/artykul-cpp17-nowy-milosciwie-panujacy-nam-standard-c-z-programisty-66/

 

 https://stackoverflow.com/questions/25612262/why-does-auto-x3-deduce-an-initializer-list

komentarz 8 listopada 2020 przez TOM_CPP Pasjonat (22,640 p.)

Zgadza się, ale zmianę tę zastosowano wstecznie w standardzie C++11 (z uwagi na możliwe problemy z kompatybilnością kodu), stąd też dzisiaj auto foo{1} kompiluje się jako zmienna typu int w C++11.

0 głosów
odpowiedź 6 listopada 2020 przez Whiskey_Taster Pasjonat (15,610 p.)
Czy zwracany wynik nie wzbudza w Tobie absolutnie żadnych podejrzeń?
komentarz 6 listopada 2020 przez rain.deer Początkujący (430 p.)
Ha, wiedziałam, że coś musi być jednak nie tak, skoro program się skompilował i nie wywalił żadnych błędów. Rzeczywiście - wynik jest bardzo duży.
komentarz 6 listopada 2020 przez rain.deer Początkujący (430 p.)
Jak zatem trzeba by poprawnie przeprowadzić to sumowanie? Wydawało mi się, że właśnie w taki sposób, że jako sumę najpierw deklaruję pierwszą liczbę z tablicy, a następnie dodawane są do niej kolejne liczby.z rosnącym licznikiem.
1
komentarz 6 listopada 2020 przez Whiskey_Taster Pasjonat (15,610 p.)
Wynik jest bardzo duży? U mnie jest bardzo mały :)
Gdyby zwróciło mi coś dużego, to bez przyjrzenia się bym w to uwierzył.

Tak, właśnie mniej więcej tak to można zrobić, ale popatrz, co Ty zrobiłaś. Sumujesz poza pętlą, więc tam się nic nie zmienia, nic nie rośnie, wszystko jest stałe.
komentarz 6 listopada 2020 przez rain.deer Początkujący (430 p.)
Właśnie przed chwilą zdałam sobie sprawę, że faktycznie, trzeba było tam zrobić jeszcze pętlę przy sumowaniu. Zmyliło mnie to, że program rzeczywiście wypisał wylosowane liczby na ekran i podał sumę. Jasne, nie dodawałam ręcznie 999 liczb, żeby sprawdzić, czy wynik jest prawdopodobny.
komentarz 6 listopada 2020 przez Whiskey_Taster Pasjonat (15,610 p.)
Można, ale też zastanów się, czy trzeba tak to sobie rozbrajać na części, czy może nie lepiej będzie wpisywać liczby do tablicy, sumować i wyświetlać je w jednej pętli :)
komentarz 6 listopada 2020 przez Oscar Nałogowiec (29,290 p.)

Nie trzeba aż tyle dodawać ręcznie, wystarczy zauważyć, że suma ~1000 liczb z zakresu <4,10> będzie w zakresie <4000, 10000>.  Uwagi:

  1. 3 razy w kodzie masz stałą 999.
  2. Do przeglądania tablic naturalne jest używanie pętli for. Oczywiście można to zrobić nawet na goto, ale program ma przede wszystkim być czytelny dla ludzi.
  3. Deklarowanie dużych tablic na stosie jest nieco ryzykowne. Akurat te parę KB się zmieści, ale jedna funkcja może wywołać drugą, ta trzecią i zajętość stosu rośnie. Są też środowiska, gdzie stos jest dość mały.
  4. Słowo "Podales" jest trochę nieodpowiednie. Raczej "Wylosowano".

Podobne pytania

+5 głosów
3 odpowiedzi 284 wizyt
0 głosów
1 odpowiedź 3,609 wizyt
pytanie zadane 31 stycznia 2018 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
0 głosów
1 odpowiedź 247 wizyt

92,555 zapytań

141,404 odpowiedzi

319,560 komentarzy

61,941 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...