A oświadczenie złożone (zwana także blok lub instrukcja blokowa) to grupa zero lub więcej instrukcji , która jest traktowana przez kompilator tak, jakby była pojedynczą instrukcją.
Bloki zaczynają się od symbolu { symbol, koniec na a } , a pomiędzy nimi umieszczane są instrukcje do wykonania. Bloków można używać wszędzie tam, gdzie dozwolona jest pojedyncza instrukcja. Na końcu bloku nie jest potrzebny średnik.
Widzieliście już przykład bloków podczas pisania funkcji, ponieważ treścią funkcji jest blok:
int add(int x, int y)
{ // start block
return x + y;
} // end block (no semicolon)
int main()
{ // start block
// multiple statements
int value {}; // this is initialization, not a block
add(3, 4);
return 0;
} // end block (no semicolon)Bloki wewnątrz innych bloków
Chociaż funkcji nie można zagnieżdżać w innych funkcjach, bloki można zagnieżdżać w innych blokach:
int add(int x, int y)
{ // block
return x + y;
} // end block
int main()
{ // outer block
// multiple statements
int value {};
{ // inner/nested block
add(3, 4);
} // end inner/nested block
return 0;
} // end outer blockKiedy bloki są zagnieżdżone, blok otaczający jest zwykle nazywany blokiem zewnętrznym a zamknięty blok nazywa się blokiem wewnętrznym lub blokiem zagnieżdżonym.
Używanie bloków do warunkowego wykonywania wielu instrukcji
Jednym z najczęstszych przypadków użycia bloków jest połączenie z if statements. Domyślnie if statement wykonuje pojedynczą instrukcję, jeśli warunek ma wartość true. Możemy jednak zastąpić tę pojedynczą instrukcję blokiem instrukcji, jeśli chcemy, aby wiele instrukcji zostało wykonanych, gdy warunek przyjmie wartość true.
Na przykład:
#include <iostream>
int main()
{ // start of outer block
std::cout << "Enter an integer: ";
int value {};
std::cin >> value;
if (value >= 0)
{ // start of nested block
std::cout << value << " is a positive integer (or zero)\n";
std::cout << "Double this number is " << value * 2 << '\n';
} // end of nested block
else
{ // start of another nested block
std::cout << value << " is a negative integer\n";
std::cout << "The positive of this number is " << -value << '\n';
} // end of another nested block
return 0;
} // end of outer blockJeśli użytkownik wprowadzi liczbę 3, ten program wyświetli:
Enter an integer: 3 3 is a positive integer (or zero) Double this number is 6
Jeśli użytkownik wprowadzi liczbę -4, ten program wypisze:
Enter an integer: -4 -4 is a negative integer The positive of this number is 4
Poziomy zagnieżdżenia bloku
Możliwe jest nawet umieszczenie bloków wewnątrz bloków wewnątrz bloki:
#include <iostream>
int main()
{ // block 1, nesting level 1
std::cout << "Enter an integer: ";
int value {};
std::cin >> value;
if (value > 0)
{ // block 2, nesting level 2
if ((value % 2) == 0)
{ // block 3, nesting level 3
std::cout << value << " is positive and even\n";
}
else
{ // block 4, also nesting level 3
std::cout << value << " is positive and odd\n";
}
}
return 0;
}Klasa poziom zagnieżdżenia (zwane także głębokość zagnieżdżenia) funkcji to maksymalna liczba zagnieżdżonych bloków, w których możesz się znajdować w dowolnym punkcie funkcji (łącznie z blokiem zewnętrznym). W powyższej funkcji znajdują się 4 bloki, ale poziom zagnieżdżenia wynosi 3, ponieważ w tym programie nie możesz nigdy znajdować się w więcej niż 3 blokach w dowolnym momencie.
Standard C++ mówi, że kompilatory C++ powinny obsługiwać 256 poziomów zagnieżdżenia - jednak nie wszystkie to obsługują (np. w chwili pisania tego tekstu Visual Studio obsługuje mniej).
Dobrze jest utrzymywać poziom zagnieżdżenia na poziomie 3 lub niższym. Tak jak zbyt długie funkcje są dobrymi kandydatami do refaktoryzacji (podziału na mniejsze funkcje), tak nadmiernie zagnieżdżone bloki są trudne do odczytania i są dobrymi kandydatami do refaktoryzacji (najbardziej zagnieżdżone bloki stają się oddzielnymi funkcjami).
Najlepsza praktyka
Utrzymuj poziom zagnieżdżenia funkcji na poziomie 3 lub niższym. Jeśli Twoja funkcja potrzebuje większej liczby zagnieżdżonych poziomów, rozważ refaktoryzację funkcji na podfunkcje.

