악마의 문법, goto
프로그래밍을 공부하면 여러가지 프로그래밍 문법과 기능과 그것을 다루는 기술들을 배우게 된다. 그렇게 배우는 문법들의 중의 하나가 바로 goto 인데, 이 goto 문에 대해서는 여러 프로그래머들의 부정적인 시각이 강하다. 오죽하면 이 goto 문을 알려주고 나서 하는 제일 첫 마디가 "가급적 사용하지 말라"이겠는가?
이 goto 문의 사용을 권장하지 않는 이유는 하나다. 코드의 가독성을 심각하게 해친다는 것이다. 물론 goto를 사용한다고 해서 무조건 코드의 가독성을 해치는 것은 아니지만 다음처럼 사용하게 된다면 많은 문제가 발생하게 될 것이다 :
void f()
{
int i = 10;
if (i > 100)
{
I100:
if (i < 200)
{
goto I200;
}
else if (i < 300)
{
goto I300;
}
}
goto I100;
I200:
cout << 1 << endl;
return;
I300:
cout << 2 << endl;
return;
}
위의 예시처럼 코드 이곳저곳을 뛰어넘게 되는 goto 문이 많을 경우나 goto I100; 부분처럼 조건에 맞지 않는 상황에서 조건문 안으로 강제 진입하게 만드는 goto 문이 있을 경우는 심각한 문제가 된다. 다른 작업자가 작업하게 되거나 작성자 자신이 재작업할 때, 코드의 흐름을 읽어내기가 어려워지고 조건문과 코드를 신뢰할 수 없게 될 것이다.
그렇다면 적절한 goto 문의 사용법이란 무엇인가? 사실 모든 프로그램은 goto 문 없이도 작성이 가능하다. 그렇기 때문에 goto문을 사용하지 않도록 권장하는 것이기도 하다. 하지만 이 goto 문 역시 적절하게 사용하면 기존의 방식보다 편하게 코드를 작성이 가능하다.
그 첫 번째 예시는 2중 이상의 반복문에서 탈출할 때이다. 반복문에서 탈출할 때 주로 사용되는 문법은 break인데, 이 break는 한 번에 단 하나의 반복문만을 탈출할 수 있다. 그래서 break로 2중 이상의 반복문을 탈출할 때는 다음과 같이 코드를 작성해야 한다 :
int main()
{
bool isBreak = false;
for (int i = 0; i < 10; i++)
{
for (int j = 0; i < 10; j++)
{
if (/*탈출조건*/)
{
isBreak = true;
break;
}
}
if (isBreak)
break;
}
}
위의 예제처럼 goto 문을 사용하지 않아도 2중 반복문을 탈출할 수 있지만, 하나의 논리 변수를 추가로 사용하고 분기문 역시 추가로 사용해야 한다. 그리고 이것은 반복문의 깊이가 깊어질 수록 사용되는 분기문의 숫자 역시 늘어나게 될 것이다(흔하지 않은 경우이기는 하다). 하지만 다음과 같이 goto 문을 사용하면 논리 변수와 반복문을 추가로 사용하지 않고도 단번에 다중 반복문을 탈출할 수 있게 된다 :
int main()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; i < 10; j++)
{
if (/*탈출조건*/)
{
goto BREAK;
}
}
}
BREAK:
}
두 번째 예시는 재입력 처리이다. 만약 1-3 값 만을 입력해야 하는 프로그램이 있다면, 그 이외의 값이 들어온다면 사용자가 값을 다시 입력하도록 프로그래밍해야할 것이다. 여기에 사용되는 일반적인 방법은 do-while 문을 사용하는 방법과 무한 loop에 진입시킨 이후에 옳은 값을 입력했다면 루프에서 탈출시키는 방법이다.
int main()
{
int i = 0;
// do-while 문을 사용하는 방법
do
{
cout << "값을 입력하세요(1~3)(do-while) :: ";
cin >> i;
} while (i < 1 || i > 3);
// 무한 loop를 사용하는 방법
while (true)
{
cout << "값을 입력하세요(1~3)(무한루프) :: ";
cin >> i;
if (i > 0 && i < 4)break;
}
}
이 경우에도 충분히 goto 문이 사용될 수 있다.
int main()
{
int i = 0;
WRONGINPUT:
cout << "값을 입력하세요(1~3)(무한루프) :: ";
cin >> i;
if (i < 1 || i > 3)
goto WRONGINPUT;
}
이렇듯 충분히 가독성을 해치지 않는 선을 지키면서도 goto 문을 사용할 수 있다. 프로그래밍을 하면서 중요한 점은 바로 이것이다. 프로그래밍에 필요한 모든 것을 최대한 활용하되 과하게 사용하지 말고 적절한 위치에 적절하게 사용하라는 것이다. 그것만으로도 코드는 충분히 깔끔해지고 작업 효율성이 상승하게 될 것이다.
[유니티 어필리에이트 프로그램]
아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.
[투네이션]
[Patreon]
[디스코드 채널]
'프로그래밍' 카테고리의 다른 글
[VisualStudio] An exception has been encountered. This may be caused by an extension. 에러 발생시 해결 방법 (0) | 2017.07.11 |
---|---|
[프로그래밍] Visual Studio 2017 Community 설치 실패 문제 해결하기(Error 0x80004003:) (0) | 2017.06.09 |
[프로그래밍] 프로그래밍 입문자들이 느끼는 어려움에 대하여 (8) | 2017.05.02 |
[프로그래밍] Debug 빌드를 유지하자 (0) | 2016.11.01 |
[프로그래밍 용어]Memory corruption(Memory stomping) (0) | 2016.11.01 |