맨위로가기

레이블 (컴퓨터 과학)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

레이블은 프로그래밍 언어에서 코드의 특정 위치를 식별하는 데 사용되는 식별자이다. C 계열 언어에서 레이블은 `goto` 문과 함께 사용되어 코드의 다른 위치로 제어를 이동시키는 데 활용되며, 스위치 문에서 `case` 및 `default`와 같은 레이블을 사용하여 실행 흐름을 제어한다. 자바스크립트에서는 반복문 앞에 레이블을 붙여 `break`나 `continue` 문으로 특정 반복문을 제어할 수 있으며, Common Lisp에서는 `tagbody` 특수 연산자를 통해 레이블을 정의하고 `go` 특수 형식을 사용하여 제어를 전송한다. BASIC에서는 행 번호가 레이블 역할을 했다. 레이블은 코드의 가독성을 저해하고 복잡성을 증가시킬 수 있으므로, 사용에 주의해야 한다.

2. C 계열 언어의 레이블

C, C++, Java 등 C 계열 언어에서 레이블은 주로 `goto` 문과 `switch` 문에서 사용된다.[9][10]

C 언어에서 레이블은 코드 내의 구문을 식별하며, 하나의 구문은 여러 개의 레이블을 가질 수 있다. 레이블은 코드 내 위치를 나타낼 뿐이며, 레이블에 도달하는 것은 실제 실행에 아무런 영향을 미치지 않는다.

고전적인 BASIC에서는 행 번호 자체가 레이블이었다. BASIC의 `GOTO` 문은 점프 대상을 지정하기 위해 이 행 번호를 사용했으며, 서브루틴 호출에 사용되는 `GOSUB` 문에서도 행 번호를 지정했다. 그러나 `goto` 문은 서브루틴을 뛰어넘는 전역 점프도 가능하여, 제어 흐름을 파악하기 어려워지는 스파게티 코드의 원인이 되기 쉬웠다. 이후 파스칼이나 C와 같은 구조적 프로그래밍 언어에서는 if 문, for 문, 서브루틴 호출 및 반환과 같은 제어 구조 관련 구문이 추상화되면서 행 번호가 필요 없어졌고, 점프의 의도를 파악하기 어려운 `goto` 문은 거의 필요하지 않게 되었다.

Java에는 `goto` 문은 존재하지 않지만, 레이블이 붙은 break 문이 준비되어 있으며, 다중 루프에서 탈출하는 등의 제한적인 용도로 사용할 수 있다. (기능이 제한된 `goto` 문의 일종이라고도 할 수 있다).

또한, 서브루틴의 엔트리 포인트를 명시하지 않는 언어에서는 레이블이 사실상 서브루틴의 엔트리 포인트를 나타내는 경우가 있다.

고전적 REXX 예시:



/* An Example */

...

IF ... THEN SIGNAL fatalError ELSE CALL whatTodo

...

whatTodo: /* 레이블 */

ARG ...

...

RETURN

fatalError: /* 레이블 */

SAY 'もう駄目。落ちます。'

EXIT


2. 1. 함수 레이블 (goto 문)

함수 레이블은 식별자와 콜론(`:`)으로 구성된다. 각 레이블은 함수 내의 문장을 가리키며, 해당 식별자는 그 함수 내에서 고유해야 한다. 다른 함수에서는 같은 이름의 레이블을 사용할 수 있다. 레이블 식별자는 자체 네임스페이스를 가지므로, 같은 이름을 가진 변수나 함수가 있어도 된다.[9]

C 언어 예시:



void foo(int number)

{

if (number < 0)

goto error;

bar(number);

return;

error:

fprintf(stderr, "Invalid number!\n");

}



여기서 `error`가 레이블이다. goto 문은 코드에서 레이블이 있는 문장으로 실행 흐름을 이동시킨다. `goto` 문 이후에는 레이블 다음의 문장이 실행된다.[9]

고전 BASIC에서는 행 번호 자체가 레이블이었다. BASIC의 `GOTO` 문은 이 행 번호를 사용하여 이동할 위치를 지정했다. 서브루틴 호출에 사용되는 `GOSUB` 문도 행 번호를 지정했지만, `goto` 문은 서브루틴을 넘어 전역 점프도 가능하여, 제어 흐름을 파악하기 어렵게 만드는 "스파게티 프로그램"이나 버그의 원인이 되기 쉬웠다.[9] 이후 파스칼이나 C와 같은 구조적 프로그래밍 언어에서는 if 문, for 문, 서브루틴 호출 및 반환과 같은 제어 구조 관련 구문이 추상화되면서 행 번호가 필요 없어졌고, 점프의 의도를 파악하기 어려운 `goto` 문은 거의 필요하지 않게 되었다.[9] 레이블을 사용하는 `goto` 문 자체는 기능으로 제공되지만, 점프 대상으로 지정할 수 있는 것은 같은 서브루틴 내에 있는 레이블뿐이며, 서브루틴을 넘는 전역 점프는 불가능하다.[9]

Java에는 `goto` 문이 없지만, 레이블을 붙인 break 문이 있어 다중 루프에서 탈출하는 등의 제한적인 용도로 사용할 수 있다. (기능이 제한된 `goto` 문의 일종이라고 볼 수 있다).[9]

C 계열 언어의 `switch` 문에서는 비교 대상인 정수 상수를 갖는 `case` 레이블과 그 외의 경우에 해당하는 `default` 레이블을 문 또는 복문에 지정할 수 있다.[10]

파스칼 예시:



procedure GotoExample(a: array of Integer);

label

100; { 레이블을 선언 }

var

i: Integer;

begin

for i := Low(a) to High(a) do begin

if a[i] < 0 then begin

WriteLn('Negative number found at: ', i);

WriteLn('Value = ', a[i]);

goto 100

end

end;

WriteLn('Negative number not found.');

100:

WriteLn('End of procedure.') { 이것이 레이블이 붙은 문 }

end;



ISO 표준 파스칼에는 C의 return 문에 해당하는 구문이 없다. 하지만 모던 파스칼/Object Pascal에서는 `Exit` 프로시저나 `Break` 프로시저가 지원되므로, 위와 같이 레이블과 `goto` 문을 사용할 필요가 없다.[11][12][13][14]

2. 2. Switch 문 레이블

`switch` 문은 여러 개의 코드 블록 중 하나를 선택하여 실행하는 제어문이다. `case` 레이블은 `case` 키워드와 정수 상수 값으로 구성되며, `switch` 문의 괄호 안의 값과 비교된다. `default` 레이블은 `default` 키워드로 구성되며, `case` 레이블과 일치하는 값이 없을 때 실행될 코드 블록을 지정한다.[9]

단일 `switch` 문 내에서 각 `case` 레이블에 연결된 정수 상수는 고유해야 한다. `default` 문은 있을 수도 있고 없을 수도 있다. `switch` 문 내에서 레이블의 순서는 제약이 없다. `case` 레이블 값이 정수 상수여야 한다는 요구 사항은 컴파일러에게 최적화를 위한 더 많은 여지를 제공하기 위해서이다.[9]

C 계열 언어의 `switch` 문에서는 비교 대상인 정수 상수를 갖는 `case` 레이블과, 그 외에 해당하는 `default` 레이블을 문 또는 복문에 지정할 수 있다.[10]

C 언어 예시:

```c

switch (die)

{

default:

printf("invalid\n");

break;

case 1:

case 3:

case 5:

printf("홀수\n");

break;

case 2:

case 4:

case 6:

printf("짝수\n");

break;

}

```

파스칼 예시:

```pascal

procedure CaseExample(x: Integer);

begin

case x of

2, 3, 5, 7:

WriteLn('A prime number less than 10.');

42:

WriteLn('The answer.');

else { 처리계에 따라서는 otherwise 도 사용 가능 }

WriteLn('The others.')

end

end;

3. 다양한 언어에서의 레이블

초기 BASIC에서는 행 번호가 레이블 역할을 했다. BASIC의 `GOTO` 문은 이 행 번호를 사용하여 점프할 위치를 지정했고, `GOSUB` 문도 서브루틴 호출에 행 번호를 사용했다. 그러나 `GOTO`는 서브루틴을 넘나드는 전역 점프가 가능하여, 코드 흐름을 파악하기 어렵게 만드는 "스파게티 프로그램"의 원인이 되기도 했다[9].

이후 파스칼, C와 같은 구조적 프로그래밍 언어들은 `if`, `for` 문, 서브루틴 호출 및 반환과 같은 제어 구조를 추상화하여 행 번호와 `GOTO` 문의 필요성을 줄였다. 이 언어들에서 `GOTO` 문은 같은 서브루틴 내의 레이블로만 점프할 수 있도록 제한되었다. 하지만 다중 루프에서 한 번에 빠져나오거나, 서브루틴 종료 전 처리를 한 곳에 모아 작성할 때는 `GOTO` 문이 유용할 수 있다.

Java는 `GOTO` 문이 없지만, 레이블을 붙인 break 문을 통해 다중 루프를 탈출하는 제한적인 기능을 제공한다. C 계열 언어의 `switch` 문에서는 `case` 레이블과 `default` 레이블을 사용하여 분기를 처리한다[10].

파스칼 예시:

```pascal

procedure GotoExample(a: array of Integer);

label

100; { 레이블을 선언 }

var

i: Integer;

begin

for i := Low(a) to High(a) do begin

if a[i] < 0 then begin

WriteLn('Negative number found at: ', i);

WriteLn('Value = ', a[i]);

goto 100

end

end;

WriteLn('Negative number not found.');

100:

WriteLn('End of procedure.') { 이것이 레이블이 붙은 문 }

end;

```

ISO 표준 파스칼에는 C의 return 문과 같은 구문은 없지만, 현대 파스칼/Object Pascal에서는 `Exit`나 `Break` 프로시저를 지원하여 레이블과 `goto` 문을 굳이 사용할 필요가 없다[11][12][13][14].

C 예시는 goto 문 및 switch 문 문서를 참조하면 된다.

서브루틴 엔트리 포인트를 명시하지 않는 언어에서는 레이블이 사실상 엔트리 포인트 역할을 하기도 한다.

고전적 REXX 예시:

```rexx

/* An Example */

...

IF ... THEN SIGNAL fatalError ELSE CALL whatTodo

...

whatTodo: /* 레이블 */

ARG ...

...

RETURN

fatalError: /* 레이블 */

SAY 'もう駄目。落ちます。'

EXIT

3. 1. 자바스크립트

javascript

top: // 가장 바깥쪽 for-loop에 레이블을 붙임.

for (var i = 0; i < 4; i++) {

for (var j = 0; j < 4; j++) {

if (j === 3 && i === 2) {

alert("i=" + i + ", j=" + j); // i=2, j=3

break top;

}

}

}

alert("i=" + i + ", j=" + j); // i=2, j=3

```

이 코드는 자바스크립트의 레이블 기능을 보여주는 예제이다. `top` 레이블은 바깥쪽 `for` 루프에 붙여졌으며, 안쪽 `for` 루프에서 `break top;` 문을 통해 바깥쪽 루프까지 한 번에 빠져나오는 것을 확인할 수 있다.

3. 2. Common Lisp

Common Lisp에서는 레이블을 정의하는 두 가지 주요 방법이 있다.

첫 번째는 `tagbody` 특수 연산자를 사용하는 것이다. C와 같이 전역 탐색을 허용하는 다른 많은 프로그래밍 언어와 달리, 레이블은 이 연산자의 컨텍스트 내에서만 접근할 수 있다. `tagbody` 내부에서 레이블은 기호로 시작하는 형태로 정의된다. `go` 특수 형식을 사용하면 이러한 레이블 간에 제어를 전송할 수 있다.[5]

```lisp

(let ((iteration NIL))

(tagbody

start

(print 'started)

(setf iteration 0)

increase

(print iteration)

(incf iteration 1)

(go check)

check

(if (>= iteration 10)

(go end)

(go increase))

end

(print 'done)))

```

두 번째는 리더 매크로 `#n=` 및 `#n#`을 사용하는 것이다. `#n=`는 바로 뒤에 오는 객체에 레이블을 지정하고, `#n#`은 해당 객체의 평가된 값을 참조한다.[6] 이러한 의미에서 레이블은 변수의 대안을 구성하며, `#n=`은 "변수"를 선언하고 초기화하고 `#n#`은 이에 접근한다. 여기서 ''n''은 레이블을 식별하는 부호 없는 10진 정수를 나타낸다.

```lisp

(progn

#1="hello"

(print #1#))

```

또한, 일부 형식은 나중에 참조하기 위해 레이블 선언을 허용하거나 요구한다. 여기에는 명명을 규정하는 특수 형식 `block`과 `named` 절로 식별할 수 있는 `loop` 매크로가 포함된다. `return-from` 특수 연산자를 사용하여 명명된 형식에서 즉시 벗어날 수 있다.

```lisp

(block myblock

(loop for iteration from 0 do

(if (>= iteration 10)

(return-from myblock 'done)

(print iteration))))

```

```lisp

(loop

named myloop

for iteration from 0

do (if (>= iteration 10)

(return-from myloop 'done)

(print iteration)))

```

C와 유사하게, 매크로 `case`, `ccase`, `ecase`[7], `typecase`, `ctypecase` 및 `etypecase`는 스위치 문을 정의한다.[8]

```lisp

(let ((my-value 5))

(case my-value

(1 (print "one"))

(2 (print "two"))

((3 4 5) (print "three four or five"))

(otherwise (print "any other value"))))

```

```lisp

(let ((my-value 5))

(typecase my-value

(list (print "a list"))

(string (print "a string"))

(number (print "a number"))

(otherwise (print "any other type"))))

3. 3. 파스칼

파스칼에서 레이블은 `label` 키워드를 사용하여 선언하고, `goto` 문을 사용하여 지정된 레이블로 이동한다[11][12][13][14].

```pascal

procedure GotoExample(a: array of Integer);

label

100; { 레이블을 선언 }

var

i: Integer;

begin

for i := Low(a) to High(a) do begin

if a[i] < 0 then begin

WriteLn('Negative number found at: ', i);

WriteLn('Value = ', a[i]);

goto 100

end

end;

WriteLn('Negative number not found.');

100:

WriteLn('End of procedure.') { 이것이 레이블이 붙은 문 }

end;

```

ISO 표준 파스칼에는 C의 return 문에 해당하는 구문이 없다. 하지만 현대 파스칼/Object Pascal 처리계에서는 `Exit` 프로시저나 `Break` 프로시저가 지원되기 때문에, 위와 같이 레이블과 `goto` 문을 사용할 필요는 없다[11][12][13][14].

3. 4. 고전적 BASIC

고전적인 BASIC에서는 행 번호 자체가 레이블 역할을 했다. BASIC의 `GOTO` 문은 점프 대상을 지정하기 위해 이 행 번호를 사용했으며, 서브루틴 호출에 사용되는 `GOSUB` 문에서도 행 번호를 지정했다. 그러나 `GOTO` 문은 서브루틴을 뛰어넘는 전역 점프도 가능했기 때문에, 제어 흐름을 파악하기 어려워져 "스파게티 프로그램"이나 버그의 원인이 되기 쉬웠다.[9]

4. 레이블 사용 시 주의사항

레이블, 특히 `goto` 문의 과도한 사용은 코드의 가독성을 떨어뜨리고 유지보수를 어렵게 만드는 "스파게티 코드"의 원인이 된다.[9] 따라서 가능한 한 if 문, for 문, while 문, switch 문 등 구조적인 제어문을 사용하여 코드의 흐름을 명확하게 표현하는 것이 좋다.

파스칼이나 C와 같은 구조적 프로그래밍 언어에서는 제어 구조 기술 구문이 고도로 추상화되어, 점프의 의도가 불분명해지기 쉬운 `goto` 문을 거의 필요로 하지 않는다.[9]

레이블을 불가피하게 사용해야 하는 경우 (예: 다중 루프 탈출)에는 주석 등을 통해 레이블의 용도와 동작 방식을 명확하게 설명해야 한다.

Java에는 `goto` 문은 없지만, 레이블이 붙은 break 문을 사용하여 다중 루프에서 탈출하는 등의 제한적인 용도로 사용할 수 있다. 이는 기능이 제한된 `goto` 문의 일종이라고 볼 수 있다.

참조

[1] 웹사이트 C Standard section 6.8.6.1 The goto statement https://web.archive.[...] 2008-07-03
[2] 웹사이트 GOTO Statement QuickSCREEN https://web.archive.[...] Microsoft 1988
[3] 웹사이트 nasm x86 Assembly http://www.cs.uaf.ed[...] 2008-07-03
[4] 웹사이트 Differences Between GW-BASIC and QBasic http://support.micro[...]
[5] 웹사이트 CLHS: Special Operator TAGBODY http://www.lispworks[...] 2020-08-18
[6] 웹사이트 CLHS: Section 2.4.8 http://www.lispworks[...] 2020-08-18
[7] 웹사이트 CLHS: Macro CASE, CCASE, ECASE http://www.lispworks[...] 2020-08-20
[8] 웹사이트 CLSH: Macro TYPECASE, CTYPECASE, ETYPECASE http://www.lispworks[...] 2020-08-20
[9] E-words goto文(go to文)とは - 意味をわかりやすく - IT用語辞典 e-Words https://e-words.jp/w[...]
[10] cppreference switch 文 - cppreference.com https://ja.cpprefere[...]
[11] Free Pascal Exit | Free Pascal https://www.freepasc[...]
[12] RAD Studio API Documentation System.Exit - RAD Studio API Documentation https://docwiki.emba[...]
[13] Free Pascal Break | Free Pascal https://www.freepasc[...]
[14] RAD Studio API Documentation System.Break - RAD Studio API Documentation https://docwiki.emba[...]
[15] 웹인용 C Standard section 6.8.6.1 The goto statement https://web.archive.[...] 2019-02-07
[16] 웹인용 GOTO Statement QuickSCREEN http://www.qbasicnew[...] Microsoft 2008-07-03
[17] 웹인용 nasm x86 Assembly http://www.cs.uaf.ed[...] 2008-07-03
[18] 웹인용 Differences Between GW-BASIC and QBasic http://support.micro[...] 2019-02-07



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com