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

Pytanie odnośnie pętli C++

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
+1 głos
492 wizyt
pytanie zadane 30 marca 2019 w C i C++ przez Ptaszor3 Użytkownik (900 p.)
otagowane ponownie 30 marca 2019 przez Arkadiusz Waluk

Dzień dobry!

Od razu chciałbym zaznaczyć, że nie mam żadnego problemu z niczym, a to pytanie zadaję z ciekawości. Dlaczego w C++ skompilowanym w GNU GCC jest możliwe coś takiego (bo zakładam, że musi być jakiś powód):

while(1);
{
      //Jakiś kod
}

Coś podobnego napisałem przez przypadek pisząc pewien program, tylko że zamiast jedynki było wyrażenie, które nie miało prawa być nie spełnione bez wykonania kodu zawartego w pętli (stracone 2 dni, kompilator nie protestował indecision ).

4 odpowiedzi

+3 głosów
odpowiedź 30 marca 2019 przez adrian17 Mentor (354,120 p.)
edycja 30 marca 2019 przez adrian17

Dlaczego w C++ skompilowanym w GNU GCC jest możliwe coś takiego (bo zakładam, że musi być jakiś powód):

Sam średnik to legalny statement. To po to, żeby pozwolić na rzeczy typu:

while (jakas_funkcja())
    ;
// po prostu wykonuj funkcję tak długo aż zwraca true

Albo makra które mogą się rozszerzać do niczego, na przykład

#if enable_assertions
#define assert(x) if(!(x)) exit(1)
#else
#define assert(x)
#endif

void f(int x){
    assert(x > 5); // może zostać rozwinięte w nicość, więc zostaje samo ";"
}

To, czy to dobry pomysł projektowy, to inny temat :) Niektóre języki na coś takiego w ogóle nie pozwalają.

(stracone 2 dni, kompilator nie protestował indecision ).

To albo masz wyłączone ostrzeżenia, albo przestarzały GCC. Od kilku wersji na dokładnie Twój kod dawałby takie ostrzeżenie:

<source>: In function 'int main()':
<source>:2:5: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
     while(1);
     ^~~~~
<source>:3:5: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
     {
     ^

A taki Clang napisałby:

<source>:2:13: warning: while loop has empty body [-Wempty-body]
    while(1);
            ^

 

+2 głosów
odpowiedź 30 marca 2019 przez Marcin Siniarski Gaduła (4,420 p.)
edycja 30 marca 2019 przez Marcin Siniarski

Jest możliwe pisanie jedno-linijkowych pętli oraz if-ów. Wiele {} może sprawić, że kod stanie się miej czytelny.

if(1)
   return true;
//...
int i = 0;
while(i > 5)
    i++;

Bardziej praktyczny przykład.

#include <fstream>
#include <iostream>
#include <string>

int main(){
    std::fstream file("test.txt", std::ios::in);
    std::string buffer = "";
    std::string line = "";
    while(std::getline(file, line))
        buffer.append(line);
    std::cout << buffer << std::endl;
    file.close();
}

Jeśli chodzi o kompilator to polecam opcje -Wall, która włącza wszystkie błędy i ostrzerzenia.

komentarz 30 marca 2019 przez adrian17 Mentor (354,120 p.)
(raczej nie chodziło tu o jedynkę, tylko o średnik)
komentarz 30 marca 2019 przez Marcin Siniarski Gaduła (4,420 p.)

Aha surprise. dzięki za wypomnienie.

+1 głos
odpowiedź 30 marca 2019 przez criss Mędrzec (172,570 p.)

Nie wiem o co ci właściwie chodzi, że jest możliwe, więc po kolei:

  • wyrażenie w warunku pętli while jest rzutowane na bool. Czyli tutaj będzie to zawsze true.
  • Jeśli w pętli jest jedna instrukcja, to można pominąć nawiasy klamrowe. Tak jest w tym przypadku, czyli w pętli wykonuje się pusta instrukcja (średnik)
  • Następnie masz nawiasy klamrowe które już nie dotyczą pętli. Za pomocą nawiasów klamrowych możesz sobie tworzyć tzw. scope-y nawet jeśli te nawiasy nie są częścią składni ifa czy pętli. Tj. zmienne utworzone wewnątrz scope-a (pomiędzy nawiasami klamrowymi) mają czas życia ograniczony do tego scope-a.
komentarz 30 marca 2019 przez Ptaszor3 Użytkownik (900 p.)
Moje pytanie dotyczyło tego, czemu w ogóle jest możliwość dodania średnika po instrukcji takiej jak np. "while(1)" i w rezultacie blok pod spodem nie jest traktowany jako "ciało" pętli dlatego, że dla mnie nie miało to żadnego sensu.
1
komentarz 30 marca 2019 przez criss Mędrzec (172,570 p.)
To myślę, że masz wytłumaczone w 3 punkcie :) Odpowiedź brzmi: bo składnia na to pozwala. Po stronie piszącego jest zadbanie o to  żeby kod był czytelny.
0 głosów
odpowiedź 31 marca 2019 przez niezalogowany
edycja 1 kwietnia 2019

A tak zupełnie innej beczki, zawsze się musi znaleźć ktoś, co napisze coś głupiego co niemnieszym czynię:

while(1) i goto nie trzeba używać. A właściwie w poważniejszych programach to while(1), to jedyna słuszny sposób używania while.

funkcja1{
while (1)
{
...........
if(warunek) break;
.................
if(warunek) continue;
.................
if(warunek) return;
.................
}
}

funkcja2 {}
{
.....................
if(warunek) exit(0);
........................
}

while(funkcja2);

tak mi jakoś jeszcze do głowy przyszło

while (w1 || ( w2 && w3) || w4) {}

while (1)

{ if(w1) continue;

.......................

if(w2 && w3)break;

if(w2 || w3) continue;

................

if(w3) break;

}

No może jeszcze trochę na temat dla naprawdę początkujących. Mi się często zdarza czegoś zapomnieć i dobrze to sobie wyrzucić na ekran

while (warunek 1)

{ cout <<"warunek 1="<<(warunek1); // czyli inna odmiana "tu jestem" jak mnie nie ma to znaczy że nie dotarłem do tego miejsca

ale cout ciężko kasować  więc lepiej zrobić funkcję f_spr ((war1)) i później każdy edytor ma funkię znajdź i zamień czyli znajdź "f_spr" i zamień na ";//;//f_spr ważne aby była na końcu linijki

a można jak w opus magnum

#include <iostream>
#define f_spr(warunek) cout<<#warunek<<"="<<warunek<<endl;

using namespace std;

int main()
{
    int a=7,b=7, c=5;
    if (a==b) cout<<100; f_spr((a==b));
    return 0;
}

 

}

 

Podobne pytania

0 głosów
2 odpowiedzi 1,523 wizyt
pytanie zadane 14 sierpnia 2019 w C i C++ przez kukulim Mądrala (6,440 p.)
0 głosów
2 odpowiedzi 771 wizyt
pytanie zadane 3 czerwca 2018 w C i C++ przez MAJ0R Obywatel (1,130 p.)
0 głosów
1 odpowiedź 725 wizyt

93,440 zapytań

142,431 odpowiedzi

322,679 komentarzy

62,802 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

...