To jest tylko wersja do druku, aby zobaczyć pełną wersję tematu, kliknij TUTAJ
Forum Oficjalnego Klubu Mitsubishi - MitsuManiaki

Komputery, RTV, AGD, Komorki - C++; ktoś się orientuje?

elektryk - 08-11-2011, 09:50

Mój komentarz dotyczy programu kolegi Kowalik, program kolegi Jawlo wydaje się poprawny.

Wewnątrz funkcji for jest zadeklarowana nowa zmienna tablica która "przesłania" zmienną tablica zadeklarowaną w funkcji main, zmienna ta "żyje" wyłącznie w ciele pętli for. Przy wyświetlaniu zmiennych na ekran jest powoływana do życia kolejna tablica która jak przypuszczam przesłania dwie poprzednie, więc jak przypuszczam program wyświetla same zera.

KowaliK - 08-11-2011, 17:20

Błąd z tablicą poprawiłem - nie wiedziałem, że robi się to bardzo podobnie jak w Pascalu. :wink:

jawlo napisał/a:
Pętla powinna zawierać warunek i<20 gdyż elementy liczone są od 0.
Dodatkowo do losowania liczb z zakresu 0-20 używamy zapisu: rand()%21


Co do warunku - czy przypadkiem nie jest tak, że i<20 losuje liczby mniejsze od 20 (czyli max 19.) a dopiero i<21 spowoduje wylosowanie liczb od 0 do 20? Podobna sytuacja z podanym przez Ciebie randem, %21 spowoduje wylosowanie liczb 1-21, a zapis jak w moim przypadku - % 20+1 wylosuje 0-20. Tak przynajmniej tłumaczył nauczyciel na programowaniu... :wink:

Kod:
#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{
    int wylosowana;
    int suma=0;
    int tab [20];
   

    srand (time(NULL));
    for (int i=0; i<20; i++)
    {
        wylosowana = rand ()%20+1;
        tab [i] = wylosowana;
        cout<<tab [i]<<endl;
        suma=suma+wylosowana;
        }

cout<<"Suma wylosowanych liczb wynosi:"<<suma<<endl;

    system("PAUSE");
    return EXIT_SUCCESS;
}



Tak wygląda efekt końcowy. Teraz tylko moje pytanie - jak powinny wyglądać wylosowane liczby w tablicy? Jedna pod drugą, czy każda obok siebie? Wydawało mi się, że powinna być prawidłowa opcja numer dwa, ale uruchomienie programu zbiło mnie z tropu - liczby wyświetlane są jedna pod drugą. :)

krzychu - 08-11-2011, 17:48

"endl" - to znak końca linii. Czyli znak "następna linia" i "powrót karetki" (inaczej kody znaków 10 i 13) :twisted:

Teraz już wiesz dlaczego są jedna pod drugą?

Jak chcesz obok siebie to zapisz tak:

cout<<tab [i]<<" ";

a na końcu daj:
cout<<endl<<"Suma wylosowanych liczb wynosi:"<<suma;

jawlo - 08-11-2011, 18:22

Elementy tablicy są numerowane od 0, tzn.
pierwszy element to tab[0],
drugi elemnet to tab[1],
....
dwudziesty to tab[19],
dwudziesty pierwszy to tab[20].

Dlatego dla 20 elementów warunek musi mieć postać for(int i=0; i<20; i++).


Kod:

   wylosowana=rand()%20+1;


Wyrażenie rand()%20 powoduje generowanie liczb z zakresu od 0 do 19.
Operator % daje resztę z dzielenia, w tym przypadku przez 20.
I tak:

19%20=19
20%20=0
21%20=1
...
czyli otrzymujemy liczby z zakresu od 0-19.

Dodatkowo tutaj liczy się priorytet operatorów (tzn. ich ważność).
Jak sądzisz jaki będzie wynik operacji:

x = 2 + 2 * 2

x będzie wynosiło 8?
Nie. x będzie równe 6.
Dlaczego?
Bo na matematyce uczyli, że najpierw wykonuje się mnożenie a potem dodawanie.
Podobnie jest w omawianej sytuacji, tzn. najpierw wykonuje się dzielenie modulo
i do wyniku dodaje się 1.

Czyli otrzymamy liczby z zakresu od 1 do 20 a miało być od 0 do 20.

KowaliK - 08-11-2011, 18:39

krzychu napisał/a:
Teraz już wiesz dlaczego są jedna pod drugą?


Tak jest. :wink:

Jawlo - całkiem zapomniałem o tym tej numeracji elementów tablicy. Ale było o tym i masz rację. Powinno być i<20 a nie i<21. :wink:

Ale co do randa nadal będę się spierał. Nie twierdzę, że to co napisałeś jest fałszem, ale dlaczego w praktyce rand()%20 losuje liczby z zakresu 1-20? Skoro wg. tego co napisałeś powinien być to zakres 1-19?

krzychu - 08-11-2011, 19:01

Z tego co pamiętam to:
rand()%20 - wylosuje 0-19
rand()%21 - wylosuje 0-20
rand()%20+1 - wylosuje 1-20

jawlo - 08-11-2011, 21:23

KowaliK napisał/a:
dlaczego w praktyce rand()%20 losuje liczby z zakresu 1-20? Skoro wg. tego co napisałeś powinien być to zakres 1-19?


Napisałem, że rand()%20 daje liczby z zakresu 0-19.
Łatwo to sprawdzić. Uruchom poniższy program i zobacz czy pojawią się zera i dwudziestki?

Kod:

#include <cstdlib>
#include <iostream>

 using namespace std;

 int main()
 {     
     srand (time(NULL));
     for (int i=0; i<1000; i++)
         cout << rand ()%20 << " ";

     system("PAUSE");
     return EXIT_SUCCESS;
 }

KowaliK - 09-11-2011, 15:35

Rzeczywiście, zwracam honor. :wink: Zmyliło mnie to +1 na końcu (summa summarum zbędne), które spowodowało wylosowanie liczb 1-20. Wychodziłoby na to, że ja coś źle zrozumiałem albo po prostu coś źle zostało podane na lekcji. Ale zdecydowanie druga opcja, bo widzę co mam zapisane w notatkach i to mnie zmyliło. Dzięki za sprostowanie. :)
Kamil_Ziomek - 12-11-2011, 19:36

Chłopaki przepraszam że się wtrącę ale widzę że macie wiedze na ten temat więc zapytam: wie ktoś jak napisać program (i wykonać) urządzenie które potrafiłoby zmieniać wyprzedzenie zapłonu ? a dokładniej działało tak:
-Oblicza liczbę obrotów (silnik 2T jedna iskra na obrót wału)
-oblicza o ile musi opóźnić impuls do modułu ( ustawiane np potencjometrem )
-opóźnia impuls

Do wykorzystania mamy fabryczny przerywacz lub jeśli będzie to za mało to jakaś przystawka np 3 punkty albo 8.

Urządzenie chcę wykorzystać do dobierania optymalnego kąta wyprzedzenia zapłony w motorach po modyfikacjach, a mikrokontrolery i jezyk c++ czy bascom w tak rozbudowanym urządzeniu mnie przerasta

elektryk - 12-11-2011, 20:43

Kamil_Ziomek napisał/a:
Chłopaki przepraszam że się wtrącę ale widzę że macie wiedze na ten temat więc zapytam: wie ktoś jak napisać program (i wykonać) urządzenie które potrafiłoby zmieniać wyprzedzenie zapłonu ? a dokładniej działało tak:
-Oblicza liczbę obrotów (silnik 2T jedna iskra na obrót wału)
-oblicza o ile musi opóźnić impuls do modułu ( ustawiane np potencjometrem )
-opóźnia impuls
Powiem tak, napisać program do tego projektu to jest banał w porównaniu z tym co trzeba później zrobić w projekcie żeby zabezpieczyć mikroprocesor od zakłóceń od impulsów zapłonu. Nie ma w sieci jakiś gotowców?
Krzyzak - 12-11-2011, 21:24

Kamil_Ziomek napisał/a:
mikrokontrolery
przede wszystkim jaki mikrokontroler, bo każdy ma swój język i odpowiednie narzędzia - inny będzie dla intela, inny dla motoroli, jeszcze inny dla ATMega itp.
jednak i tak w większości przypadków piszesz w asemblerze, więc polecam kontrolery oparte na motoroli
musisz też znać układ we-wy, bo odczyt danych z portów to kwestie odpowiednich adresów... nie można napisać czego uniwersalnego
i też polecę - jak elektryk - spróbować poszukać gotowców

Kamil_Ziomek - 15-11-2011, 21:19

Do wykorzystania mam wszystko co mają w pobliskim sklepie z elektroniką (link ) i mam tam jakieś Attiny , pic-e. Myślałem żeby zrobić przystawkę którą się mocuje do wału lub jakiegoś elementu który się z nim obraca (krzywka, koło magnesowe) i zrobić to na fototrazystorach i diodach na podczerwień , więc zakłócenia nie będą aż tak duże a elementem wykonawczym będzie moduł zapłonowy. Skrzynka w której będzie urządzenie dodatkowo ekranaowana.

Jeszcze jedno pytanie- ma ktoś może jakiś fajny kurs pisania takich programów bo mam chęć się nauczyć czegoś nowego :)

elektryk - 15-11-2011, 21:41

Kamil_Ziomek napisał/a:
Do wykorzystania mam wszystko co mają w pobliskim sklepie z elektroniką (link ) i mam tam jakieś Attiny , pic-e.
Dokładny procesor nie jest krytyczny, przy dzisiejszych cenach i dostępności, spokojnie jesteś w stanie zamówić nawet zza granicy.
Kamil_Ziomek napisał/a:
Myślałem żeby zrobić przystawkę którą się mocuje do wału lub jakiegoś elementu który się z nim obraca (krzywka, koło magnesowe) i zrobić to na fototrazystorach i diodach na podczerwień , więc zakłócenia nie będą aż tak duże a elementem wykonawczym będzie moduł zapłonowy. Skrzynka w której będzie urządzenie dodatkowo ekranaowana.
Źródłem zakłóceń nie będzie element wykonawczy tylko sam łuk elektryczny w świecy i impuls prądu przepływający przez cewkę i przewody wysokiego napięcia. Fototranzystory to kiepski pomysł, są mało odporne na kurz i brud, lepiej dopasować jakiś gotowy moduł. Nawet od poczciwego trabanta w wersji zapłonem elektronicznym można dopasować czujnik położenia wału.
Kamil_Ziomek napisał/a:
Jeszcze jedno pytanie- ma ktoś może jakiś fajny kurs pisania takich programów bo mam chęć się nauczyć czegoś nowego :)
Poczytaj sobie tutaj http://www.elektroda.pl/r...ic.php?t=139965 w ogóle portal elektroda to kopalnia wiedzy i znajdziesz tam różnych ludzi chętnych do pomocy.
KowaliK - 17-12-2011, 15:40

Wracam z powrotem, niestety - mam problem z sortowaniem bąbelkowym. Program, który mam do napisania ma losować 10 liczb, a następnie je posortować. W pierwszej opcji je najzwyczajniej (bez żadnych optymalizacji) w świecie sortuje, drugi ma zawierać optymalizację, a trzeci również ma zawierać optymalizację z użyciem funkcji bool. Przy okazji każdy program ma wyświetlać ilość porównań oraz cykli. Naskrobałem coś takiego:

Kod:
#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{
    const int n=10;
    int tab[n];
    int x;
   
   
    srand(time(NULL));
    for ( int n=0; n<10; n++)
    {
       int wylosowana;       
       wylosowana=rand()%10+1;
       tab[n]=wylosowana;
       cout<<tab[n]<<" ";
     
    }
     cout<<" "<<endl;
      for (int g=0; g<n-1; g++)
        for (int k=0; k<n-1; k++)
          if(tab[k]>tab[k+1])
        {
         
          x=tab[k];
          tab[k]=tab[k+1];
          tab[k+1]=x;
          cout<<tab[k]<<" ";
        } 
   
    system("PAUSE");
    return EXIT_SUCCESS;
}


Program losuje 10 liczb, ale przy sortowaniu nie wiem skąd wyświetla 20 zupełnie innych liczb. Gdzie popełniłem błąd?

Co do drugiej opcji, to jak dobrze rozumiem należy dodać przy forze:

Kod:
for(k=0; k<n-1-g; k++)


A co do trzeciej opcji znalazłem taki fragment w sieci:

Kod:
    void bubble_sort(T* tab, int n) {
        bool swapped; // Czy zamieniono w ostatnim obrocie?
 
        do {
            swapped = false;
            for (int i = 0; i < n - 1; ++i) {
                if (tab[i] > tab[i + 1]) {
                    swap(tab[i], tab[i + 1]);
                    swapped = true;
                }
            }
        } while (swapped);
    }


Ale tutaj pojawia się swap, którego jeszcze nie przerobiliśmy i nie mam o nim bladego pojęcia, w związku z czym nie mogę go użyć. Jak to ugryźć? :(

jawlo - 17-12-2011, 23:30

KowaliK napisał/a:
Program losuje 10 liczb, ale przy sortowaniu nie wiem skąd wyświetla 20 zupełnie innych liczb. Gdzie popełniłem błąd?


Wszystko jest w porządku.
Wypisywanie wyników sortowania umieściłeś w pętli w instrukcji IF.
Oznacza to, że zostanie tylko wyświetlona liczba, która zostaje przesunięta.

Masz błąd w zakresie pętli (powinny być warunki b< n oraz k<n).

Wyświetlanie powinno chyba wyglądać tak?
Kod:

       for (int g=0; g<n; g++)
       {
         for (int k=0; k<n; k++)
         {   
            if(tab[k]>tab[k+1]) 
            {     
               x=tab[k];
               tab[k]=tab[k+1];
               tab[k+1]=x;
            } 
            cout << tab[ k ]<< " ";
        }   
        cout << endl;
      }


Cytat:

Co do drugiej opcji, to jak dobrze rozumiem należy dodać przy forze:

Kod:
for(k=0; k<n-1-g; k++)



Poprawnie :)

Cytat:

Ale tutaj pojawia się swap, którego jeszcze nie przerobiliśmy i nie mam o nim bladego pojęcia, w związku z czym nie mogę go użyć. Jak to ugryźć? :(


swap to nic innego jak zamiana miejscami, czyli te trzy instrukcje, które masz w instrukcj IF.
Kod:

               x=tab[k];
               tab[k]=tab[k+1];
               tab[k+1]=x;


Aby policzyć liczbę zamian, należy w instrukcji IF umieścić zmienną i ją inkrementować (np. zamiana++ ).
Aby policzyć cykle należy umieścić w zewnętrznej pętli licznik cykli (np. cykl++).



Powered by phpBB modified by Przemo © 2003 phpBB Group