2009-07-23 9 views
15

Kiedy używam nawiasów klamrowych wokół bloku kodu case w C++, aby zlokalizować zmienne należy umieścić break wewnątrz lub na zewnątrz bloku?gdzie umieścić break in switch/case statement z blokami

case FOO: // 'break' inside 
    { 
    int i; 
    doStuff(); 
    break; 
    } 

case BAR: // 'break' outside 
    { 
    int i; 
    doStuff(); 
    } 
    break; 

Dzięki.

+0

Czy mógłbyś wyjaśnić, proszę, pytanie, jak to nie ma sensu ... –

+4

Myślę, że to ma sens ... –

+0

Ma sens, ale jest to przykład kodu, który nie sprawi, że stanie się jaśniejszy – dmckee

Odpowiedz

19

To kwestia stylu.

Położyłbym break poza nawiasu zamykającego tylko po to, aby był bardziej czytelny.

+5

Zgadzam się. Nie zgadzam się (myślę, że jest bardziej czytelny w środku, ale to tylko mój styl: -0) –

2

To naprawdę zależy od logiki kodu i sposobu użycia nawiasów klamrowych, ale w celu uzyskania poprawnej odpowiedzi, jeśli włożysz jedną do środka, spróbuj umieścić wszystkie w środku.

14

Umieszczasz to gdzie chcesz. Upewnij się, że zachowujesz spójność przez cały czas trwania projektu. (Osobiście wystawiłem go na zewnątrz.)

+0

reguły spójności! +1 – xtofl

+0

spójność +1 +1 +1 :-) –

+0

prostu zniszczony swoją konsystencję @xtofl. @MartinYork;) –

4

I zazwyczaj umieścić break wewnątrz szelki, na przykład:

switch (foo) { 
    case bar: { 
     int x = 5; 
     printf("%d\n", x); 
     break; 
    } 
    case baz: { 
     // ... 
     break; 
    } 
} 

Jednakże, ponieważ to moja zasada jestem wolny złamać go (gra słów nie przeznaczonych), kiedy chcę.

1

Moim zdaniem należy unikać lokalnych zmiennych i bloków w instrukcjach przełączania. Poza tym powinieneś unikać długich, złożonych lub nawet kaskadowych instrukcji przełączania. Ale bez reguły bez wyjątku ... Wolę napisać instrukcję break po bloku.

4

Powinien pojawić się po.

Na przykład:

switch(value) 
{ 
    case 0: 
    { 
    // this ... 
    // that ... 
    // and the other ... 
    } 
    break; 
} 

Edytowane tekst poniżej

to głównie w celu poprawienia czytelności i konserwacji oto przykład.

switch (value) 
{ 
    case 0: 
    // Do this... 
    // Do that... 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

i

switch (value) 
{ 
    case 0: 
    // Do this... 
    // Do that... 
    if (ObjectWithinScope.Type == Fault) 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

teraz porównać z

switch (value) 
{ 
    case 0: 
    { 
    // Do this... 
    // Do that... 
    } 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

i

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

Po uruchomieniu natknąć się przypadki zagnieżdżonych sprawozdania przełącznika może się rzeczywiście bardzo mylące .

Tylko wskaźnik.

Niektórzy z was wciąż zastanawiają się, w co się pakuję. Oto jest. Fragment starego kodu przestał działać i nikt nie mógł zrozumieć, dlaczego.To wszystko sprowadza się do kawałka kodu strukturalnego jak następuje:

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

zajęło dużo czasu, aby zmusić ten kod, ale na sprawdzenie logów zmian było pierwotnie jako followws:

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
      // *** A line of code was here *** 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

Wprawdzie oryginalny kod nie był zgodny z samym sobą, ale z powodu przerwy w nawiasach klamrowych kod skompilowany, gdy jedna linia kodu została usunięta przez przypadek. Gdyby przerwa była poza nawiasami, to nie miałaby.

+7

"powinien"? czemu? –

+0

Poprzez umieszczenie go po bloku i maintainalbility czytelność kodu jest jaśniejszy - Mam edytowane moją odpowiedź pokazać przykładem. – ChrisBD

1

To nie ma znaczenia, o ile Ty i Twój zespół robicie to samo konsekwentnie. Nawet wtedy nie jest to duży problem, jeśli różni członkowie zespołu robią to inaczej.

Ja osobiście wolę po. Rozumowanie jest takie, że daje pewne rozróżnienie między mechanizmem instrukcji switch (przeskakiwanie do, wykonywanie rzeczy i wydostawanie się), a kodem w nawiasach klamrowych, który jest wyłącznie związany z "działaniem" sprawy.

np

switch(value) 
{ 
    case 0: 
     { 
      // code here 
     } 
     break; 

    default: 
     { 
      assert(!"unhandled value in switch"); 
     } 
     break; 
} 

I tylko używać {} dla przypadku, gdy potrzebuje zmienne lokalne, ale jeśli mogę użyć {} dla każdego przypadku, umieścić je we wszystkich przypadkach.

Zwykle zawsze definiuję domyślny przypadek, aby potwierdzić, czy jest jakaś nieoczekiwana wartość. To niesamowite, jak często jeden z nich potwierdza pożar, aby przypomnieć o braku przypadku.

0

Chodzi o styl, ale umieścić go po jak rozumiem definicji jako:

switch (variable) 
{ 
    case expression: 
     statement; 
     break; 
    default: 
     statement; 
     break; 
} 

którym oświadczenie to albo pojedyncze polecenie lub blok. Przerwa jest oddzielona od tej instrukcji lub bloku. I tak, dodam przerwę po domyślnym, chociaż jest zbędne. Również podniosłem nawiasy klamrowe wokół instrukcji. Zbyt wiele razy dodałem jeszcze jedno stwierdzenie, aby przerwać zakres. I dodajemy przerwę do domyślnej, ponieważ zmieniono domyślną: na case - i dodałem coś po niej. Kodowanie obronne to twój przyjaciel.

jednak mogę tylko znaleźć dokumentację do rzeczywistej definicji poprzez Microsoft jako:

selection-statement: 
    switch (expression) statement 

labeled-statement: 
    case constant-expression : statement 
    default : statement 

co wskazywałoby, że powinno być w środku.

Jednak myślę, że na zewnątrz jest bardziej czytelna z punktu widzenia czytelników, ale z pewnością jest subiektywna.

0

Ponieważ standard nie ogranicza wyboru pozycji do stwierdzenia, że ​​można wybrać dowolną opcję. Osobiście używam następujący styl:

switch (some_var) { 
     case 1: { 
      // lot of code here 
     } break; 
     case 2: /* one call */ break; 
     case 3: /* one call */ break; 
     case 4: { 
      // lot of code here again 
     } break; 
    } 
4

Wszyscy zgadzają się, że chcemy wyraźnie rozpoznawalny rozróżnienie maszyn switch/case... i rzeczywistych działań wykonywanych w każdym przypadku.

nich, chyba że naprawdę prawie nicdzieje się w każdym przypadku (proste zadanie lub tak), proponuję użyć switch jedynie jako dyspozytor, i przekazać to, co „prawdziwe” z funkcjami pomocniczymi.To automatycznie rozwiązuje problem zmiennych lokalnych typu case i całkowicie eliminuje potrzebę użycia aparatów ortodontycznych.

switch(operation) { 
    case cnegation: r = -value; break; 
    case cinversion: r = 1./r; break; 
    case cfaculty: { 
    double r = value; 
    while(value != 1) 
     r *= --value; 
    } 
    break; 
} 

powinny następnie stać się

switch(operation) { 
    case cnegation : r = negate (value) ; break; 
    case cinversion: r = invert (value) ; break; 
    case cfaculty : r = faculty(value) ; break; 
} 
0

Istnieje wiele przemawia za tym stylu tylko za pomocą jednej instrukcji na razie, i nigdy nie używając nawiasów. Na przykład:

 
switch(cond) { 
default: foo(); break; 
case 0: bar(); break; 
case 1: baz(); break; 
} 

Używając tego stylu, twoje pytanie jest dyskusyjne.

+0

Dlaczego upadek? Pytanie dotyczy wyłącznie stylu, a to jest odpowiedź na styl? –

1

Nie lubię wprowadzenie jakichkolwiek nawiasach w instrukcji switch. Osobiście, jeśli jest to skomplikowana operacja, lubię wstawiać ją do funkcji. Nie ma nic bardziej irytującego niż zobaczenie instrukcji zmiany, w której pomiędzy każdą "skrzynką" znajdują się setki linii kodu, a na dodatek niektóre z nich są powtarzane w różnych przypadkach, co uniemożliwia konserwację.

Na przykład:

switch(blah) 
{ 
case 1: 
    // do one thing 
    break; 

case 2: 
    doManyThings(); 
    break; 

default: 
    // something 
    break; 
} 
+0

Posiadanie zmiennej lokalnej wewnątrz instrukcji case nie oznacza, że ​​mam złożoną instrukcję z dużą ilością kodu wewnątrz. – jackhab

0

realna odpowiedź: kompilator nie obchodzi. To kwestia preferencji.

umieścić je wewnątrz, jak google style guide.

przypadku korzystania z szelkami I jak klamra otwieranie się w tej samej kolumnie, co klamry zamykającej (która różni się od google).

switch (var) { 
    case 0: 
    { 
    ...  
    break; 
    } 
    case 1: 
    { 
    ... 
    break; 
    } 
    default: 
    assert(false); 
} 
0

Moje zdanie ... Zobacz przykład poniżej.

Wciśnij wszystkie przypadki przełącznika i zamknij klamrę przełącznika pod słowem kluczowym switch, podobnie jak w przypadku instrukcji if. Ilekroć jest to potrzebne, ta sama reguła dla każdej instrukcji case: otwórz nawiasy po kolumnie pół następującej po instrukcji case i zamknij je pod słowem kluczowym case, a następnie wcięcia zawartości każdego z oświadczeń case, w tym słowa kluczowego break.

Keep it spójne (wcięcia i wsporniki staże) i krótkie (nie więcej niż 5-10 linie kodu za case oświadczeniu. Złożone projekty nie powiodła się z powodu źle wcięta switch sprawozdania zbyt dużo kodu w nich.

switch (number) { 

     case 1: 
      logFileStderr(VERBOSE, "MESSAGE: switch without brackets...\n"); 
      break; 

     case 2: { 
      logFileStderr(VERBOSE, "MESSAGE: switch with brackets...\n"); 
      break; 
     } 

     default: 
      logFileStderr(VERBOSE, "WARNING: Unknown option...\n"); 
      break; 
    }