Sens istnienia średnika w pętli do while

0

witam dopiero zaczynam się uczyć c++ i zastawia mnie jedna rzecz a nie moge znaleźć odpowiedzi na nią w książce dlaczego w pętli do while nawet jak używam średników żeby zrobić cały blok instrukcji musze postawić średnik po while. O co mi chodzi dokładniej z tego co zrozumiałem to kiedy robimy jakiś blok instrukcji np.:

while
{
  cout  <<"Witaj kuba";
  cout <<"Jak sie masz";
}

wiem że to jest totalnie bez sensu ale chodzi mi o cos innego chodzi mi oto ze po while nie dajemy srednika a jak uzywam petli do while to wyglada to tak

do
{
  cout <<"Podaj wysokosc";
  cin >>wysokosc;
}
while (wysokosc >2000);
{
   cout <<"wysokosc za niska !";
 cout <<"Zwieksz ja";
}

chodzi mi oto ze gdy nie ma srednika po while wywala blad a przeciez jest on tu chyba nie potrzebny. Proszę o pomoc bo chciałbym to rozumieć :)

1

Taka jest składnia: https://www.tutorialspoint.com/cplusplus/cpp_do_while_loop.htm
Co tu rozumieć, Postępuj zgodnie z instrukcjami i tyle.

7

Ten kod:

do
{
  cout <<"Podaj wysokosc";
  cin >>wysokosc;
}
while (wysokosc >2000);
{
   cout <<"wysokosc za niska !";
 cout <<"Zwieksz ja";
}

działa inaczej, niż tego oczekujesz. Wszystko przez niedbałe jego formatowanie. Pętla while ma taką konstrukcję:

while(/* warunek */)
{
  /* instrukcje */
}

Nie ma żadnych średników. Natomiast pętla do while taką:

do
{
  /* instrukcje */
}
while(/* warunek */);

Tu średnik zakańcza ciało pętli i jest wymagany.

Twój drugi kod (ten, który podałem na początku tego posta) zawiera pętlę do while, na końcu której średnik jest potrzebny. A po linijce z while, masz zgrupowane dwie instrukcje, które nie powinny być zgrupowane, bo nie należą do żadnego sensownego bloku kodu.

Inaczej pisząc, Twój kod po sformatowaniu wygląda tak:

do
{
  cout << "Podaj wysokosc";
  cin >> wysokosc;
}
while(wysokosc > 2000);

{
  cout << "wysokosc za niska !";
  cout << "Zwieksz ja";
}

a po usunięciu zbędnych klamer, tak:

do
{
  cout << "Podaj wysokosc";
  cin >> wysokosc;
}
while(wysokosc > 2000);

cout << "wysokosc za niska !";
cout << "Zwieksz ja";

Jeśli więc skupimy się na pętli i usuniemy z tego przykładu kawałki do niej nienależące, zostanie tyle:

do
{
  cout << "Podaj wysokosc";
  cin >> wysokosc;
}
while(wysokosc > 2000);

Problem polega na tym, że Twój przykład wygląda jak hybryda pętli while i do while, co utrudnia zrozumienie kodu. Dlatego już od pierwszych napisanych linijek kodu, powinieneś uczyś się jego prawidłowego formatowania. Puste linie pozwalają wizualnie dzielić kod na bloki, co sprzyja czytelności.

0

Dodam jeszcze że jeżeli w pętli while wykonujemy tylko jedną instrukcję, a nie kilka instrukcji ograniczonych {} to po instrukcji średnik musi być

0

@Miang: każda instrukcja musi być zakończona średnikiem, nieważne czy jedna czy kilka. To nie Pascal. ;)

0

Dzięki za pomoc ! :)

0

Furious, jakich zbędnych ? :P

#include <iostream>
	using std::cout;

int main()
{
	int i=3;

	{
		int i=5;
		cout<<i<<std::endl;
	}
	cout<<i<<std::endl;
}

nie do końca są takie zbędne :P

for(struct{int a,b;}loop{0,7};loop.a<loop.b; { if(loop.b<4)loop.b+=1; else loop.b+=2 } ) cout<<loop.a;

mogłem nieco pokręcić bo piszę to na tej stronie ale { } nie są tam do końca zbędne xD

przy okazji jak się używa struct w forze to można też użyć np. double :)

0

Jeśli klamry grupujące instrukcje nie należą do żadnej specyficznej konstrukcji języka, to ich istnienie jest nadmiarowe, zmniejszające czytelność kodu i utrudniające jego analizę. A to że kompilator nie uznaje ich za błąd składniowy, niczego nie zmienia.

0

W C++ niekoniecznie są nadmiarowe, bo wymuszają destrukcję obiektów zdeklarowanych wewnątrz klamry.
Jeśli ten destruktor zwalnia jakiś zasób, staje się on dostępny dla kodu po klamrze zamykającej.

void foo()
{
    {
        SomeKlass bar;
    }
    // już jesteśmy po destruktorze obiektu bar.
}
0

Zgoda, tyle że te klamry należą do specyficznej konstrukcji języka – tu specyficzna jest destrukcja zasobów. Natomiast w kodzie pytacza nie pełnią one żadnej sensownej funkcji, dlatego są nadmiarowe i należy je usunąć.

1

Przykład nienadmiarowych klamer:

#include <windows.h>
#include <gdiplus.h>
...
void OnPaint(HWND hwnd)
{
	PAINTSTRUCT ps;
	BeginPaint(hwnd, &ps);
	{
		Gdiplus::Graphics g(ps.hdc);
		g.Clear(Gdiplus::Color::AliceBlue);
	}
	EndPaint(hwnd, &ps);
}

myk polega na tym, że destruktor obiektu Graphics musi się wykonać przed EndPaint.
Można by fragment z klamrami wyciągnąć do osobnej funkcji (OnReallyPaint?).
Można by wymyśleć smartpointerowe opakowanie na BeginPaint/EndPaint.
Można by obudować klasę Graphics tak by wywoływała te funkcje automatycznie.
Ale to wszystko przekombinowane rozwiązania - klamry załatwiają sprawę.

Można by wreszcie dodać ifa sprawdzającego wynik BeginPaint i klamry stają się niezbędne :-)

    if (BeginPaint(hwnd, &ps))
    {
        Gdiplus::Graphics g(ps.hdc);
        g.Clear(Gdiplus::Color::AliceBlue);
    }

1 użytkowników online, w tym zalogowanych: 0, gości: 1