답변:
AFAIK, C ++는 Java 및 기타 언어처럼 이름 지정 루프를 지원하지 않습니다. goto를 사용하거나 사용하는 플래그 값을 만들 수 있습니다. 각 루프의 끝에서 플래그 값을 확인하십시오. true로 설정되면 해당 반복에서 벗어날 수 있습니다.
goto
그것이 최선의 선택이라면 if 를 사용하는 것을 두려워하지 마십시오 .
goto
불량 프로그래머와 실용 프로그래머 의 두 가지 유형의 프로그래머가 사용 합니다. 전자는 자명하다. 만약 당신이 그것들을 잘 사용하기로 선택한다면 후자는 "악"이라는 개념이 더 적을 때 소위 "악"개념을 사용합니다. 때때로 사용해야하는 일부 C ++ 개념 (매크로, goto 's, 전 처리기, 배열)에 대한 이해를 돕기 위해이 내용을 읽으십시오. parashift.com/c++-faq-lite/big-picture.html#faq-6.15
goto
드물게 사용 하는 것이 최선의 선택 임을 제외하고는 맞습니다 . 루프를 자체 기능 ( inline
속도가 걱정되는 경우)에 넣지 마십시오 return
.
아니요,로 망치지 마십시오 break
. 사용에 대한 마지막 남은 요새입니다 goto
.
람다를 사용하여 명시 적 답변을 추가하려면 다음을 수행하십시오.
for (int i = 0; i < n1; ++i) {
[&] {
for (int j = 0; j < n2; ++j) {
for (int k = 0; k < n3; ++k) {
return; // yay we're breaking out of 2 loops here
}
}
}();
}
물론이 패턴에는 특정 제한이 있으며 분명히 C ++ 11 만 있지만 매우 유용하다고 생각합니다.
중첩 루프를 해제하는 또 다른 방법은 두 루프를 별도의 함수로 분리 return
하고 종료하려는 경우 해당 함수에서 분리 하는 것입니다.
물론 이것은 return
끝 이외의 다른 곳에서 함수에서 명시 적으로 해야하는지 여부에 대한 또 다른 논쟁을 불러옵니다 .
continue_processing
에서 코드 블록의 실행을 제어하는 부울 변수 (예 :와 같은 )로 흩어진 함수가있는 곳에서 작업 한 시스템 .
break 는 그것을 포함하는 가장 안쪽의 루프 만 빠져 나옵니다.
goto 를 사용 하여 여러 루프에서 벗어날 수 있습니다 .
브레이크 기능 [...]을 사용하는 것이 적절합니까?
break와 goto를 사용하면 프로그램의 정확성에 대해 추론하기가 더 어려워 질 수 있습니다. 이에 대한 토론은 여기를 참조하십시오 : Dijkstra는 미쳤다 .
break
or를 사용하는 것이 좋습니다 return
.
break
와 return
를 통해 장점을 가지고 goto
당신은 그들이 이동하는 위치를 찾기 위해 레이블을 위해 사냥을 할 필요가 없습니다. 예, 그 아래에는 일종의 goto
매우 제한적인 것이 있습니다. 그것들은 프로그래머의 패턴 매칭 두뇌에 의해 무제한보다 해독하기가 훨씬 쉽습니다 goto
. 따라서 IMO가 바람직합니다.
goto
.
이 answear가 이미 제시되었지만 좋은 접근 방식은 다음을 수행하는 것입니다.
for(unsigned int z = 0; z < z_max; z++)
{
bool gotoMainLoop = false;
for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
{
for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
{
//do your stuff
if(condition)
gotoMainLoop = true;
}
}
}
gotoMainLoop
매 사이클마다 점검 되기 때문에 코드가 "quite"느려집니다
goto
사용하면 코어를 더 읽기 쉽고 더 나은 성능으로 만들 수 있습니다.
여러 개의 중첩 루프를 제거하는 좋은 방법 중 하나는 코드를 함수로 리팩터링하는 것입니다.
void foo()
{
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
// If condition is true
return;
}
}
}
}
goto는 중첩 루프를 끊는 데 매우 도움이 될 수 있습니다
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
for (l = 0; l < 1000; l++){
....
if (condition)
goto break_me_here;
....
}
}
}
}
break_me_here:
// Statements to be executed after code breaks at if condition
goto
이 상황에서 a 가 유효 하다고 생각합니다 .
break
/ 를 시뮬레이트하려면 continue
다음을 원합니다.
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
i
. 따라서 이동 i++
하기 전에
PHP와 같은 다른 언어는 break (즉, break 2;)에 대한 매개 변수를 허용하여 중단하려는 중첩 루프 수준을 지정하지만 C ++에서는 그렇지 않습니다. 루프 전에 false로 설정 한 부울을 사용하고, 중단하려는 경우 루프에서 true로 설정 한 부울을 사용하고, 중첩 된 루프 다음에 조건부 나누기, 부울이 true로 설정되었는지 확인하여이를 해결해야합니다. 그렇다면 예.
나는 이것이 오래된 포스트라는 것을 안다. 그러나 나는 조금 논리적이고 간단한 대답을 제안 할 것입니다.
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < conditionj; j++)
{
for(unsigned int k=0; k< conditionk ; k++)
{
// If condition is true
j= conditionj;
break;
}
}
}
j = conditionj
대신 복잡한 술어가있는 경우 작동하지 않으므로 확장 성이 떨어지는 솔루션 은 아닙니다 j < conditionj
.
하나의 bool
변수로 여러 루프를 분리 하십시오 (아래 참조).
bool check = true;
for (unsigned int i = 0; i < 50; i++)
{
for (unsigned int j = 0; j < 50; j++)
{
for (unsigned int k = 0; k < 50; k++)
{
//Some statement
if (condition)
{
check = false;
break;
}
}
if (!check)
{
break;
}
}
if (!check)
{
break;
}
}
이 코드에서 우리는 break;
모든 루프입니다.
그만한 가치가 있는지 확실하지 않지만 몇 가지 간단한 매크로를 사용하여 Java의 명명 된 루프를 에뮬레이션 할 수 있습니다.
#define LOOP_NAME(name) \
if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
{ \
[[maybe_unused]] CAT(_namedloop_break_,name): break; \
[[maybe_unused]] CAT(_namedloop_continue_,name): continue; \
} \
else
#define BREAK(name) goto CAT(_namedloop_break_,name)
#define CONTINUE(name) goto CAT(_namedloop_continue_,name)
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
사용법 예 :
#include <iostream>
int main()
{
// Prints:
// 0 0
// 0 1
// 0 2
// 1 0
// 1 1
for (int i = 0; i < 3; i++) LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << i << ' ' << j << '\n';
if (i == 1 && j == 1)
BREAK(foo);
}
}
}
다른 예시:
#include <iostream>
int main()
{
// Prints:
// 0
// 1
// 0
// 1
// 0
// 1
int count = 3;
do LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << ' ' << j << '\n';
if (j == 1)
CONTINUE(foo);
}
}
while(count-- > 1);
}
try ... catch를 사용할 수 있습니다.
try {
for(int i=0; i<10; ++i) {
for(int j=0; j<10; ++j) {
if(i*j == 42)
throw 0; // this is something like "break 2"
}
}
}
catch(int e) {} // just do nothing
// just continue with other code
한 번에 여러 루프에서 벗어나야하는 경우 종종 예외입니다.
for-loop의 의미는 일반적으로 지정된 횟수만큼 실행됨을 나타 내기 때문에 for-loop를 해제하는 것은 조금 이상합니다. 그러나 모든 경우에 나쁘지는 않습니다. 컬렉션에서 무언가를 검색하고 그것을 찾은 후에 깨고 싶다면 유용합니다. 그러나 C ++에서는 중첩 루프를 해제 할 수 없습니다. 레이블이 지정된 구분을 사용하여 다른 언어로되어 있습니다. 라벨과 고토를 사용할 수 있지만 밤에 가슴 앓이를 줄 수 있습니다. 그래도 가장 좋은 옵션 인 것 같습니다.