• 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++

Object Storage Arubacloud
+1 głos
316 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 Ekspert (344,860 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 Ekspert (344,860 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,590 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,590 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,228 wizyt
pytanie zadane 14 sierpnia 2019 w C i C++ przez kukulim Mądrala (6,440 p.)
0 głosów
2 odpowiedzi 550 wizyt
pytanie zadane 3 czerwca 2018 w C i C++ przez MAJ0R Obywatel (1,130 p.)
0 głosów
1 odpowiedź 461 wizyt

92,551 zapytań

141,393 odpowiedzi

319,522 komentarzy

61,936 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...