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.
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...
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)
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.
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.
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. 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++).
|
|
|