Dziwny problem z pętlą do while!


(przemekKK) #1
int wybor;

do

	{

	cout << "1" << endl << endl;

	cout << "2" << endl << endl;

	cout << "3" << endl << endl;

	cout << "4" << endl << endl;

	cout << "5" << endl << endl;

	cout << "6" << endl << endl;

	cout << "7" << endl << endl;

	cin >> wybor;


	} while ((wybor!=0) || (wybor!=2) || (wybor!=3) || (wybor!=4) || (wybor!=5) || (wybor!=6) || (wybor!=7));

Czy ktoś wie dlaczego pętla wykonuje się ponownie nawet jeśli wybiorę 1, 2 lub 3?


(Sawyer47) #2

Chyba nie przemyślałeś warunku pętli. Warunek jest zawsze spełniony. Każda liczba jest różna od zera lub różna od 2.


(przemekKK) #3

Chodzi mi o to, że po naciśnięciu 0, 1, 2 lub 3 pętla już ma się nie wykonywać.


(Sawyer47) #4

No to to jest podstawowa matematyka. x < 0 || x > 3 czyli słównie x jest mniejsze od 0 lub większe od 3. Czyli nie należy do zbioru { 0, 1, 2, 3 } (uwzględniając, że to typ int i przechowuje liczby całkowite)


(przemekKK) #5
char wybor;


	do

	{


	//system("CLS");


	cout << "1" << endl << endl;

	cout << "2" << endl << endl;

	cout << "3" << endl << endl;

	cout << "4 " << endl << endl;

	cout << "5 << endl << endl;

	cout << "6 " << endl << endl;

	cout << "7" << endl << endl;

	cin >> wybor;


	} while ((wybor!='0') || (wybor!='2') || (wybor!='3') || (wybor!='4') || (wybor!='5') || (wybor!='6') || (wybor!='7'));

To co ja mam zrobić, aby po naciśnieciu 1,2 lub 3 pętla nie wykonywała się dalej. Menczę się z tym już od 3 godz.


(Matheosh) #6

Przecież tutaj zostało dokładnie to opisane.

do

{

...

}

while(...);

Wykonuj do momentu aż warunek w nawiasie jest spełniony, wpisujesz wybor>3 czyli pętla się wykonuje do momentu, aż zmienna wybor jest większa od 3 , jeśli wpiszesz 0,1,2,3 pętla zakończy swe działanie.


(przemekKK) #7

Ale ja mam char!


(somekind) #8

Może i masz char, ale przede wszystkim problemy z logiką.

Pętla wykonuje się, dopóki warunek w nawiasach od while jest prawdziwy. Chcesz ją przerwać, więc musisz sprawić, aby na Twoje żądanie warunek ten stał się fałszywy. Jak rozumiem - chcesz, aby działo się tak po naciśnięciu '0', '1', '2' albo '3'. Więc po co wpisujesz jakieś '4', '5', '6' i '7' w tym warunku, skoro te znaki Cię nie interesują?

I kolejna sprawa - czy Ty wiesz, co się dzieje w Twoim programie, tutaj:

(wybor!='0') || (wybor!='2') || (wybor!='3') || (wybor!='4') || (wybor!='5') || (wybor!='6') || (wybor!='7')

Sprawdzasz, czy podany znak nie jest równy sześciu innym znakom. Nic dziwnego, że pętla się nie przerywa, bo KAŻDY znak jest równy tylko samemu sobie i żadnemu innemu. A przecież Ty chcesz sprawdzić, czy podany znak nie jest równy '0' i '1' i '2' i '3'. Z naciskiem na spójnik "i", więc alternatywa, której używasz, tutaj odpada.

I jeszcze taka rada - nie siedź 3 godziny nad banalnym problemem. Idź sobie na rower, ryby poczytać książkę, co lubisz. Jak odpoczniesz, to może Cię olśni :slight_smile:


(Sawyer47) #9

somekind , || to inaczej or - czyli "lub". Owszem, może czasem w języku mówionym, mówiąc "i" chodzi j o "lub" z punktu widzenia logiki matematyczne. Tutaj akurat warunek: różny od 0 i różny od 1 jest prawdziwe dla wszystkich liczb poza 0 i 1. Natomiast ze spójnikiem "lub" jest prawdziwe dla każdej liczby.


(somekind) #10

Niedługo mnie 8 lat od kiedy przeczytałem to w tej książce, ale dziękuję za przypomnienie. :wink:

Może, czasem. Ja jednak jestem upierdliwym pedantem, ponadto staram się być purystą, i wyrażam się ściśle :slight_smile:

Ja odnosiłem się do problemu autora, a nie Twoich wypowiedzi.

Alternatywa jest prawdziwa wtedy, gdy którykolwiek jej element jest prawdziwy, zaś koniunkcja, gdy wszystkie są prawdziwe. Prawda?

Dlatego kod autora:

(wybor!='0') || (wybor!='2') || (wybor!='3') || (wybor!='4') || (wybor!='5') || (wybor!='6') || (wybor!='7')

jest zawsze prawdziwy, bo fałszywy mógłby być jedynie w przypadku, gdyby każdy warunek był fałszywy.

Pobawmy się w Pana Debbugera:

  • wpisujemy '3', sprawdzany jest warunek 3 != 0, wynik jest true, więc pętla się powtarza;

  • wpisujemy '0', sprawdzany jest warunek 0 != 0, co daje false, więc sprawdzany jest następny 0 != 2, wynik true, więc pętla sie powtarza;

  • wpisujemy '9', sprawdzany jest warunek 9 != 0, co daje true, więc pętla się powtarza;

  • i tak w każdym przypadku.

Po prostu w warunku jest alternatywa, powinna być koniunkcja. Trzeba sprawdzić, czy wybór jest różny od każdej niepożądanej liczby, aby pętle powtórzyć, autor tego nie robi. Problem banalny :slight_smile:

Ale nie mam zamiaru rzucać tu gotowym kodem. Jak ja sie uczyłem programować, nie miałem w domu telefonu, a co dopiero mówić o forum. Sam musiałem do wszystkiego dojść, niech autor też się trochę pomęczy, będzie miał z tego większą satysfakcję i zapamięta na dłużej, skąd ten "błąd".


(przemekKK) #11

Może by tak zagnieździć pętle do while?


(Cosik Ktosik) #12

przemekKK , przemyśl to (z nastawianiem na słowo koniunkcja, po naszemu "i"), nie trzeba żadnych pętli zagnieżdżonych.


(przemekKK) #13

Wypróbowałem z &&, ale po wpisaniu np. 222 pętla się także przerywała. Więc wykombinowałem tak:

char wybor;


	cout << endl << "1 " << endl << endl;

	cout << "2 " << endl << endl;

	cout << "3 " << endl << endl;

	cout << "4 " << endl << endl;

	cout << "5" << endl << endl;

	cout << "6 " << endl << endl;

	cout << "7 " << endl << endl;

	cin >> wybor;



	switch (wybor)

	{

	case 1:


	case 2:


	case 3:



	case 4:


	case 5:


	case 6: 


	case '7': koniec();break;

	default: menu();

	}

Jeżeli żaden wariant nie zostanie wybrany to dzięki default funkcja menu() zostanie wywołana ponownie.


(somekind) #14

Jakich pętli zagnieżdżonych? Ktoś tu wspominał o zagnieżdżaniu? Bo nie ja.

Przemyślałem to - wystarczy wpisać:

while ((wybor!='0') && (wybor!='1') && (wybor!='2') && (wybor!='3'))

i działa.

Jesteś już w tym momencie dobijający.

Dzieje się tak z uwagi na fakt, że typ char przechowuje jeden znak. Więc po wpisaniu "222" zmienna wybór ma wartość "2", więc normalnym jest, że pętla się przerywa. Wystarczy użyć string zamiast char i cudzysłowów zamiast apostrofów.


(Cosik Ktosik) #15

somekind , faktycznie, to przemekKK , napisał o zagnieżdżaniu. Zapomniałem dodać informacje, że to do niego i już to poprawiłem. Z tobą zgadzam się w 100%. Ale plama. #-o


(somekind) #16

Spoko :slight_smile: Bo już myślałem, że całkiem niezrozumiale piszę :wink: