Goto 편집하기

이동: 둘러보기, 검색

경고: 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. 로그인하거나 계정을 생성하면 편집자가 아이디(ID)으로 기록되고, 다른 장점도 있습니다.

편집을 되돌릴 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.
최신판 당신의 편집
2번째 줄: 2번째 줄:
  
 
== Goto ==
 
== Goto ==
프로그램의 흐름을 바꾸는 기본적인 명령으로, 일부 고급 언어에서 공통적으로 사용되는 명령이다. 원래는 [[CPU]]의 명령어 중에는 JUMP라는 것이 있는데, 이를 이용하면 코드의 특정 부분으로 바로 이동할 수 있다. 이것을 이용하면 조건분기나 반복 등을 구현할 수 있어서 많이 사용되는데, 이것을 고급 언어에 유사하게 사용할 수 있도록 구현한 것이 바로 GOTO다. 제대로 사용하면 상당히 유용하게 쓸 수도 있으나 보통의 IT 커뮤니티와 대부분의 개발자들 사이에서는 사용이 꺼려지는 기능이다. GOTO가 없는 언어도 많이 찾아볼 수 있는데, 몇 가지 이유가 있어서 그렇다. 일단 프로그래밍 언어 중 명령의 실행 순서를 중요하게 여기지 않는 언어들, 대표적으로 순수 함수형 언어(Haskell 등)와 일부 논리 프로그래밍 언어들(대표적으로 SQL)은 GOTO가 없다. 또한 일부 특수 목적 프로그래밍 언어 중에서 과거 시점으로 되돌아가는 게 불가능한 언어들(VHDL 등)이 있는데 이들 언어들에도 GOTO가 없다. 이들 언어들에는 앞으로도 영원히 GOTO가 추가될 일이 없는데, 언어의 서술 논리 자체에 '시간'이라는 개념이 없기 때문이다. 명령의 실행 순서가 중요하지만 GOTO를 지원하지 않는 경우도 있다. (대표적으로 Java의 경우 예약어로서는 존재하지만 기능이 없다.) 대부분의 프로그래밍 언어는 조건문과 반복문을 지원해주는데, 이를 이용하면 GOTO가 없어도 프로그램을 작성하는 데에 문제가 거의 없다. 게다가 아래에서 서술할 문제점 때문에 잘 지원하지 않는다. 참고로 GOTO는 동일 함수 내에서의 점프만 가능하다. 함수라는 개념이 없는 언어(어셈블리어, GW-BASIC 등)는 소스 코드 아무 곳으로나 점프가 가능하지만 함수 개념이 있는 언어에서는 함수 바깥의 레이블로 GOTO를 하려고 하면 컴파일 에러가 난다. 물론 이 함수도 뛰어넘어서 특정 코드로 이동하는 것이 아주 불가능한 것은 아니다. 예를 들어서 C/C++의 경우 setjmp, longjmp라는 함수를 제공하는데, 이것을 이용하면 함수를 넘어서 점프도 가능하다. 다만 이 함수가 하는 기능은 '현재의 스택의 상태와 코드의 위치'를 저장하여 특정 경우에 그 위치로 복귀하는 것이라서, 아직 setjmp를 만나지 않았거나 setjmp가 끝난 경우에는 점프할 수 없다. 무슨 말인지 이해가 잘 안 갈수도 있는데, C++의 try, catch, throw가 하는 역할과 비슷하다고 생각하면 된다.<ref name = "나무위키">〈[https://namu.wiki/w/GOTO GOTO - 나무위키]〉, 《나무위키》</ref>
+
프로그램의 흐름을 바꾸는 기본적인 명령으로, 일부 고급 언어에서 공통적으로 사용되는 명령이다. 원래는 CPU의 명령어 중에는 JUMP라는 것이 있는데, 이를 이용하면 코드의 특정 부분으로 바로 이동할 수 있다. 이것을 이용하면 조건분기나 반복 등을 구현할 수 있어서 많이 사용되는데, 이것을 고급 언어에 유사하게 사용할 수 있도록 구현한 것이 바로 GOTO다. 제대로 사용하면 상당히 유용하게 쓸 수도 있으나 보통의 IT 커뮤니티와 대부분의 개발자들 사이에서는 사용이 꺼려지는 기능이다. GOTO가 없는 언어도 많이 찾아볼 수 있는데, 몇 가지 이유가 있어서 그렇다. 일단 프로그래밍 언어 중 명령의 실행 순서를 중요하게 여기지 않는 언어들, 대표적으로 순수 함수형 언어(Haskell 등)와 일부 논리 프로그래밍 언어들(대표적으로 SQL)은 GOTO가 없다. 또한 일부 특수 목적 프로그래밍 언어 중에서 과거 시점으로 되돌아가는 게 불가능한 언어들(VHDL 등)이 있는데 이들 언어들에도 GOTO가 없다. 이들 언어들에는 앞으로도 영원히 GOTO가 추가될 일이 없는데, 언어의 서술 논리 자체에 '시간'이라는 개념이 없기 때문이다. 명령의 실행 순서가 중요하지만 GOTO를 지원하지 않는 경우도 있다. (대표적으로 Java의 경우 예약어로서는 존재하지만 기능이 없다.) 대부분의 프로그래밍 언어는 조건문과 반복문을 지원해주는데, 이를 이용하면 GOTO가 없어도 프로그램을 작성하는 데에 문제가 거의 없다. 게다가 아래에서 서술할 문제점 때문에 잘 지원하지 않는다. 참고로 GOTO는 동일 함수 내에서의 점프만 가능하다. 함수라는 개념이 없는 언어(어셈블리어, GW-BASIC 등)는 소스 코드 아무 곳으로나 점프가 가능하지만 함수 개념이 있는 언어에서는 함수 바깥의 레이블로 GOTO를 하려고 하면 컴파일 에러가 난다. 물론 이 함수도 뛰어넘어서 특정 코드로 이동하는 것이 아주 불가능한 것은 아니다. 예를 들어서 C/C++의 경우 setjmp, longjmp라는 함수를 제공하는데, 이것을 이용하면 함수를 넘어서 점프도 가능하다. 다만 이 함수가 하는 기능은 '현재의 스택의 상태와 코드의 위치'를 저장하여 특정 경우에 그 위치로 복귀하는 것이라서, 아직 setjmp를 만나지 않았거나 setjmp가 끝난 경우에는 점프할 수 없다. 무슨 말인지 이해가 잘 안 갈수도 있는데, C++의 try, catch, throw가 하는 역할과 비슷하다고 생각하면 된다.<ref name = "나무위키">〈[https://namu.wiki/w/GOTO GOTO - 나무위키]〉, 《나무위키》</ref>
  
 
== 장점 ==
 
== 장점 ==
GOTO문의 남용은 소스코드의 이해를 어렵게 만들지만, 적절한 사용은 오히려 소스코드의 [[가독성]]과 [[명료성]]을 높이는 경우가 있다. 가령 다중 [[반복문]]에서의 탈출, 에러에 대한 예외 처리 등 일부 작업에 한해서는 GOTO문을 사용하는 경우가 더 명료한 경우도 있다. 다만 위의 경우라도 로직 레벨에서의 탈출이나 함수화 시킨 후에 return등을 이용하는 등 GOTO문을 쓰지 않기를 권고하는 경우도 많다. 대표적인 예시로 리눅스 커널 소스코드를 까봐도 심심찮게 GOTO문을 발견할 수 있다.[4] 안정성이 매우 중요한 [[운영체제]] [[커널]]에서 사용하는 것이다. 위의 코드도 리눅스 커널의 코드다. 터부시 되기에는 나름대로 쓰임새가 있는 것도 사실. 그러나 초보자에게는 많은 경우에 일종의 금기로써 가르친다. GOTO문이 유용한 경우는 어디까지나 특수한 케이스이고 잘못 사용했을 경우의 어디서부터 손대야할지 모르는 스파게티를 만들어버리는데다가 초보자의 경우 특히 가능성이 높기 때문. [[C]]언어보다 고수준 언어를 사용한다면 예외처리는 exception(try-catch)으로, [[C++]]같이 리소스 해제가 수동이지만 RAII를 지원하는 경우는 RAII를 사용하자. 용법은 같으면서 가독성은 증가한다. 다만 그런거 없는 C언어에서는 예외처리와 동적 리소스 해체에 goto를 주로 사용한다. 이 GOTO문은 어셈블리어의 산물이다보니 어셈블리어에서는 이러한 기능의 사용이 강제된다. 어셈블리어에서는 프로그램의 흐름을 제어할 수 있는 구문이 Jump 계열의 명령어밖에 없는데, 이는 무조건적으로 혹은 특정 조건을 만족하면 명령어에서 지시하는 프로그램 카운터로 이동하는 구문이다. 고급 언어로 쓰인 코드도 컴파일해서 [[어셈블리]] 소스를 열어보면 전부 GOTO문의 반복형으로 되어있다. 정확히는 jmp 계열 명령(jmp, jnz, jz 등. CPU의 아키텍처에 따라 다르다)으로 바뀐다.<ref name = "나무위키></ref>
+
GOTO문의 남용은 소스코드의 이해를 어렵게 만들지만, 적절한 사용은 오히려 소스코드의 가독성과 명료성을 높이는 경우가 있다. 가령 다중 반복문에서의 탈출, 에러에 대한 예외 처리[3] 등 일부 작업에 한해서는 GOTO문을 사용하는 경우가 더 명료한 경우도 있다. 다만 위의 경우라도 로직 레벨에서의 탈출이나 함수화 시킨 후에 return등을 이용하는 등 GOTO문을 쓰지 않기를 권고하는 경우도 많다. 대표적인 예시로 리눅스 커널 소스코드를 까봐도 심심찮게 GOTO문을 발견할 수 있다.[4] 안정성이 매우 중요한 운영체제 커널에서 사용하는 것이다. 위의 코드도 리눅스 커널의 코드다. 터부시 되기에는 나름대로 쓰임새가 있는 것도 사실. 그러나 초보자에게는 많은 경우에 일종의 금기로써 가르친다. GOTO문이 유용한 경우는 어디까지나 특수한 케이스이고 잘못 사용했을 경우의 어디서부터 손대야할지 모르는 스파게티를 만들어버리는데다가 초보자의 경우 특히 가능성이 높기 때문. C언어보다 고수준 언어를 사용한다면 예외처리는 exception(try-catch)으로, C++같이 리소스 해제가 수동이지만 RAII를 지원하는 경우는 RAII를 사용하자. 용법은 같으면서 가독성은 증가한다. 다만 그런거 없는 C언어에서는 예외처리와 동적 리소스 해체에 goto를 주로 사용한다. 이 GOTO문은 어셈블리어의 산물이다보니 어셈블리어에서는 이러한 기능의 사용이 강제된다. 어셈블리어에서는 프로그램의 흐름을 제어할 수 있는 구문이 Jump[5] 계열의 명령어밖에 없는데, 이는 무조건적으로 혹은 특정 조건을 만족하면 명령어에서 지시하는 프로그램 카운터로 이동하는 구문이다. 고급 언어로 쓰인 코드도 컴파일해서 어셈블리 소스를 열어보면 전부 GOTO문의 반복형으로 되어있다.[6] 정확히는 jmp 계열 명령(jmp, jnz, jz 등. CPU의 아키텍처에 따라 다르다)으로 바뀐다.<ref name = "나무위키></ref>
 
=== 예시 ===
 
=== 예시 ===
 
==== 재입력 처리====
 
==== 재입력 처리====
만약 1-3 값 만을 입력해야 하는 프로그램이 있다면,  그 이외의 값이 들어온다면 사용자가 값을 다시 입력하도록 프로그래밍 해야할 것이다. 여기에 사용되는 일반적인 방법은 [[do while]] 문을 사용하는 방법과 무한 loop에 진입시킨 이후에 옳은 값을 입력했다면 루프에서 탈출시키는 방법이다.
+
만약 1-3 값 만을 입력해야 하는 프로그램이 있다면,  그 이외의 값이 들어온다면 사용자가 값을 다시 입력하도록 프로그래밍 해야할 것이다. 여기에 사용되는 일반적인 방법은 do-while 문을 사용하는 방법과 무한 loop에 진입시킨 이후에 옳은 값을 입력했다면 루프에서 탈출시키는 방법이다.
  
 
  int main()
 
  int main()
31번째 줄: 31번째 줄:
 
  {
 
  {
 
     int i = 0;
 
     int i = 0;
 +
 
  WRONGINPUT:
 
  WRONGINPUT:
 
     cout << "값을 입력하세요(1~3)(무한루프) :: ";
 
     cout << "값을 입력하세요(1~3)(무한루프) :: ";
37번째 줄: 38번째 줄:
 
         goto WRONGINPUT;
 
         goto WRONGINPUT;
 
  }
 
  }
이렇듯 충분히 가독성을 해치지 않는 선을 지키면서도 goto 문을 사용할 수 있다. 프로그래밍을 하면서 중요한 점은 바로 이것이다. 프로그래밍에 필요한 모든 것을 최대한 활용하되 과하게 사용하지 말고 적절한 위치에 적절하게 사용하라는 것이다. 그것만으로도 코드는 충분히 깔끔해지고 작업 효율성이 상승하게 될 것이다.<ref name = "티스토리">wergia, 〈[https://wergia.tistory.com/52 [프로그래밍] 악마의 문법, goto :: 베르의 프로그래밍 노트]〉, 《티스토리》, 2017-06-01</ref>
+
이렇듯 충분히 가독성을 해치지 않는 선을 지키면서도 goto 문을 사용할 수 있다. 프로그래밍을 하면서 중요한 점은 바로 이것이다. 프로그래밍에 필요한 모든 것을 최대한 활용하되 과하게 사용하지 말고 적절한 위치에 적절하게 사용하라는 것이다. 그것만으로도 코드는 충분히 깔끔해지고 작업 효율성이 상승하게 될 것이다.<ref>wergia, 〈[https://wergia.tistory.com/52 [프로그래밍] 악마의 문법, goto :: 베르의 프로그래밍 노트]〉, 《티스토리》, 2017-06-01</ref>
 +
 
  
 
== 단점 ==
 
== 단점 ==
65번째 줄: 67번째 줄:
 
     return;
 
     return;
 
  }
 
  }
위의 예시처럼 코드 이곳저곳을 뛰어넘게 되는 goto 문이 많을 경우나 goto I100; 부분처럼 조건에 맞지 않는 상황에서 조건문 안으로 강제 진입하게 만드는 goto 문이 있을 경우는 심각한 문제가 된다. 다른 작업자가 작업하게 되거나 작성자 자신이 재작업할 때, 코드의 흐름을 읽어내기가 어려워지고 조건문과 코드를 신뢰할 수 없게 될 것이다.<ref name = "티스토리"></ref>
+
위의 예시처럼 코드 이곳저곳을 뛰어넘게 되는 goto 문이 많을 경우나 goto I100; 부분처럼 조건에 맞지 않는 상황에서 조건문 안으로 강제 진입하게 만드는 goto 문이 있을 경우는 심각한 문제가 된다. 다른 작업자가 작업하게 되거나 작성자 자신이 재작업할 때, 코드의 흐름을 읽어내기가 어려워지고 조건문과 코드를 신뢰할 수 없게 될 것이다.<ref>wergia, 〈[https://wergia.tistory.com/52 [프로그래밍] 악마의 문법, goto :: 베르의 프로그래밍 노트]〉, 《티스토리》, 2017-06-01</ref>
  
 
{{각주}}
 
{{각주}}
  
 
== 참고자료 ==
 
== 참고자료 ==
* 〈[https://namu.wiki/w/GOTO GOTO - 나무위키]〉, 《나무위키》
 
* wergia, 〈[https://wergia.tistory.com/52 [프로그래밍] 악마의 문법, goto :: 베르의 프로그래밍 노트]〉, 《티스토리》, 2017-06-01
 
  
 
== 같이 보기 ==
 
== 같이 보기 ==
77번째 줄: 77번째 줄:
 
* [[베이직]]
 
* [[베이직]]
  
{{프로그래밍|검토 필요}}
+
{{프로그래밍|토막글}}

위키원에서의 모든 기여는 다른 기여자가 편집, 수정, 삭제할 수 있다는 점을 유의해 주세요. 만약 여기에 동의하지 않는다면, 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다 (자세한 사항은 위키원:저작권 문서를 보세요). 저작권이 있는 내용을 허가 없이 저장하지 마세요!

취소 | 편집 도움말 (새 창에서 열림)