IDL/Data Type & Format

구조체(Structure)에 관하여

이상우_IDL 2025. 6. 24. 15:51
728x90

IDL에서 지원되는 자료형(Data Type)들을 보면 정수(Integer), 실수(Float), 문자(String) 등과 같은 아주 기본적인 것들 그리고 긴 정수(Long Interger), 64비트 긴 정수(64bit Long Interger), 2배 정밀도 실수(Double Precision) 등과 같이 값의 비트(bit) 수가 더 높아서 더 많은 단계의 값들을 표현할 수 있도록 해주는 것들이 있습니다. 그런데 이러한 것들 외에도 일종의 특수 자료형이라고 할 만한 것들도 있는데 구조체(Structure), 포인터(Pointer), 리스트(List), 해쉬(Hash) 등이 이러한 범주에 해당됩니다. 제가 이 블로그에서 예전에 리스트와 해쉬에 관해서는 관련 게시물들을 올린 바 있습니다. 참고로 이 게시물들의 링크는 아래와 같습니다.

 

리스트(List) [1]

리스트(List) [2]

해쉬(Hash)

 

이와 같은 자료형들은 그 특성을 보면 복합형 자료형이라고 볼 수 있습니다. 즉 자료형이나 구조가 서로 다른 다수의 항목들이 함께 공존하는 집단의 형태를 갖기 때문입니다. 그러한 자료형으로서 리스트 및 해쉬를 먼저 소개하였지만 이 자료형들은 IDL 8.0 버전부터 지원되기 시작하였습니다. 그런데 이러한 복합형 자료형으로서 그 이전부터 오랫동안 지원되어온 터줏대감 격의 자료형이 있는데 그것이 바로 구조체(Structure)입니다. 나중에 도입된 리스트나 해쉬보다는 유연성이 좀 덜하긴 하지만, 예전부터 많이 활용되어왔고 지금도 여전히 활용 가치가 높은 자료형이라고 볼 수 있습니다. 그래서 오늘은 이 구조체라는 자료형에 관하여 자세히 소개해보도록 하겠습니다.

 

원래 구조체(Structure)라는 개념은 IDL뿐 아니라 다른 프로그래밍 언어들에서도 널리 사용되어 왔습니다. 사실 “구조체”라는 용어로 표현하는 것이 정식으로 맞는 것인지는 모르겠지만, 일단 여기서는 이러한 명칭으로 통일하도록 하겠습니다. 어쨌든 구조체라는 것은 각종 변수 및 배열 등과 같은 다양한 형태의 아이템들을 모아놓은 복합적인 집합체라고 할 수 있습니다. 즉 자료형 및 형태가 다양한 여러가지 항목들을 하나의 덩어리로 묶어놓은 개념입니다. 그래서 구조체를 흔히 복합형 자료형(Compound Data Type)이라고 부르기도 합니다. 구조체 뿐만 아니라 앞서 이미 언급했던 리스트, 해쉬, 포인터 등의 자료형들 역시 이러한 범주에 속합니다.


그러면 구조체라는 개념의 이해를 돕기 위하여 Tottenham Hotspur라는 축구 클럽에 관한 정보를 예로 들어보겠습니다. 이 팀의 이름인 “Tottenham Hotspur”는 문자형 값에 해당됩니다. 그리고 이번 시즌 현재까지의 승점이 몇 점이냐는 정수형 값이 되겠지요. 그리고 손흥민, Maddison, Romero 등 모든 선수들의 이름과 같은 정보는 문자형 값들이 모아져 있는 하나의 문자형 배열이 될 것입니다. 선수들 각자의 신장(Height)은 실수형 값이 될 것이므로 이 값들을 모으면 실수형 배열이 됩니다. 그리고 선수들 각자 현재까지 기록중인 골수는 정수형 값이 될 것이므로 이 값들을 모으면 정수형 배열이 됩니다. 이런 식으로 다양한 정보들이 여러가지 형태의 변수 또는 배열 등의 형태로 존재하지만, 이들은 모두 Tottenham Hotspur라는 축구팀에 관한 정보들로서 이들을 한 덩어리로 묶어버리면 바로 Tottenham Hotspur라는 구조체가 된다고 이해하면 쉬울 것입니다. 그러면 이 구조체의 이름을 TOT라고 명명하고 정의해봅시다. 예를 들면 다음과 같은 방식으로 하면 됩니다. 선수 인원은 편의상 4인으로 가정하였습니다.


TOT = {team, name:'Tottenham Hotspur', point:38, names:STRARR(4), heights:FLTARR(4), goals:INTARR(4)}

 

구조체를 정의할 때에는 위와 같이 집합 괄호 { }를 사용합니다. 그리고 이 구조체의 이름은 TOT이지만, { }안에서 맨 처음에 있는 team이라는 항목은 일종의 내부적인 이름에 해당됩니다. 구조체를 생성할 때 위와 같이 내부 이름까지도 함께 정의하는 경우도 있고 그렇지 않은 경우도 있습니다. 내부 이름 없이 정의된 구조체는 익명 구조체(Anonymous Structure)라고 부릅니다. 반면 내부 이름을 갖도록 정의된 구조체는 기명 구조체(Named Structure)라고 부릅니다. 구조체를 정의하는데 있어서 내부 이름을 사용하느냐 마느냐는 선택의 문제입니다만, 여기서는 위와 같이 내부 이름을 갖는 기명 구조체가 되도록 TOT를 정의하였습니다. 여기서 굳이 내부 이름을 사용하여 기명 구조체로 정의한 이유는 잠시후 설명하겠습니다.

 

그리고 위의 { } 안에서 내부 이름의 바로 뒤에 이어지는 코마(,)로 분리된 항목들은 구조체 내에 포함될 다양한 종류의 정보들에 해당되는데 이러한 개별 항목을 일반적으로 필드(Field) 또는 태그(Tag)라고 부릅니다. 그리고 각 항목을 보면 콜론 기호(:)가 있는데, 콜론 기호의 좌측은 필드명 또는 태그명에 해당되고 콜론의 우측은 해당 필드(태그)에 대응되는 실제 값이 됩니다. 즉 다음과 같은 방식입니다.

 

필드명 : 필드값

name : 'Tottenham Hotspur'

point : 38

names : STRARR(4)

heights : FLTARR(4)

goals : INTARR(4)

 

즉 위의 정의에 의하면 name이라는 필드에 'Tottenham Hotspur'라는 문자값이 대응되어 있고 point라는 필드에는 38이라는 정수값이 대응되어 있습니다. 그리고 names라는 필드에는 4개의 값을 담는 문자형 배열이 대응되어 있고, heights라는 필드에는 4개의 값을 담는 실수형 배열이 대응되어 있고, goals라는 필드에는 4개의 값을 담는 정수형 배열이 대응되어 있습니다. 일단 point는 38이라는 값이 이미 명시된 필드인 반면 names, heights, goals의 경우는 배열의 형태만 존재할 뿐 배열 내 원소값들은 아직 정의되지 않은 상태입니다.

 

어쨌든 중요한 것은 이와 같은 방식으로 하나의 구조체를 생성할 수 있다는 것입니다. 그리고 하나의 구조체 내에 포함될 수 있는 항목들 즉 필드(태그)들은 다양한 자료형의 변수 또는 배열이 될 수 있다는 것도 주목할 필요가 있습니다. 즉 구조체라는 것은 다양한 종류의 자료들을 한꺼번에 담을 수 있는 그릇의 역할을 합니다. 배열의 경우는 배열 내에 포함될 수 있는 원소값들은 모두 동일한 자료형이 되어야 하는 반면, 구조체의 경우는 구조체 내에 포함될 수 있는 항목들이 서로 자료형이나 형태가 달라도 아무 상관이 없다는 것입니다. 이러한 특성 때문에 구조체는 프로그래밍에 있어서 굉장한 유연성과 자유를 부여합니다.

 

위와 같이 구조체가 일단 정의된 상태에서 구조체 내 필드 각각에 대한 세부적인 정의를 추가적으로 수행할 수도 있습니다. 예를 들어서 4명의 선수들 전원의 이름에 해당되는 문자값들을 다음과 같이 대입할 수 있습니다.

 

TOT.names = ['Son', 'Maddison', 'Romero', 'Solanke']


여기서 TOT.names는 TOT라는 구조체의 names라는 필드를 뜻하는 것으로서, 이와 같이 구조체 내의 특정 필드를 지칭할 때에는 닷(.) 기호를 사용한다는 것을 유념해야 합니다. 만약 4명의 선수들 각자의 이번 시즌 골수를 데이터로 입력한다면 다음과 같은 방식으로 하면 됩니다.

 

TOT.goals = [7, 9, 1, 9]

 

만약 여기서 누군가가 골을 더 넣는다면 개별적으로 바꾸는 것도 가능합니다. 예를 들어 손흥민 선수가 골을 하나 더 넣을 경우라면 다음과 같이 하면 됩니다.

 

TOT.goals[0] = 8

 

여기서는 TOT라는 구조체의 goals라는 필드가 배열인 상태에서 이 배열의 첫번째 값이 손흥민 선수에 해당되므로 인덱스 0으로 접근한 것입니다.

 

어쨌든 위와 같은 방식으로 구조체를 정의하고 닷(.) 기호를 사용하여 구조체 내부의 각 필드에 접근할 수 있다는 것 정도까지가 가장 중요한 부분이라고 봐도 될 것 같습니다. 그리고 아까 익명 구조체와 기명 구조체라는 개념을 언급하였는데요. 각각 경우가 나름의 특성이 있습니다. 위에서 정의된 TOT라는 구조체의 경우 team이라는 내부 이름이 포함된 기명 구조체로 정의되어 있습니다. 만약 이와 같이 내부 이름을 사용하여 기명 구조체의 형태로 정의된 구조체가 있을 경우라면, 동일한 내부 이름을 사용하여 형태만 똑같은 또 다른 구조체를 복제하여 생성할 수가 있습니다. 이러한 예를 보여드리기 위하여 TOT를 기명 구조체로 정의했던 것입니다. 즉 예를 들어서 또 다른 축구팀(예를 들면 Arsenal)에 대한 구조체를 동일한 형태로 복제하여 만들고자 한다면 다음과 같이 하면 됩니다.


ASL = {team}

 

그러면 앞서 만들었던 TOT라는 구조체와 형태가 완전히 동일한 ASL이라는 구조체가 만들어집니다. 물론 이와 같이 기존에 이미 있던 기명 구조체의 내부 이름을 활용하여 복제된 구조체의 경우는 처음 생성된 직후에는 그 내부에는 필드들은 존재하지만 각 필드에 대한 구체적인 값은 아직 정의되지 않은 상태가 됩니다. 즉 ASL이라는 구조체에는 name이란 필드는 존재하지만, 그 필드에 대응되는 문자형 값은 아직 정의가 되지 않은 상태입니다. 또한 point라는 필드 역시 존재는 하지만 그 필드에 대응되는 정수형 값은 아직 정의되지 않은 상태입니다. 따라서 만약 다음과 같이 그 내용을 프린트하라고 해도 아직은 그냥 0이란 값과 빈 문자(null)만 출력될 것입니다.

 

PRINT, ASL.point

PRINT, ASL.name

 

따라서 이와 같이 내용이 정의되어있지 않은 필드들에 대해서는 그 내용을 직접 채워줘야 합니다. 예를 들면 다음과 같습니다.

 

ASL.point = 74

ASL.name = 'Arsenal'

 

그리고 나머지 names, heights, goals 필드들에 대해서도 마찬가지 방법으로 구체적인 정보들을 입력해주면 됩니다. 예를 들면 names라는 필드에 대한 구체적인 정보를 입력하려면 다음과 같이 하면 됩니다.

 

CHL.names = ['Odegaard', 'Rice', 'Saka', 'Martinelli']


그리고 이미 존재하는 구조체에 관한 정보를 총체적으로 살펴보고자 한다면 다음과 같이 HELP 명령을 /STRUCTURES 키워드를 함께 사용하는 것이 좋습니다.

 

HELP, TOT, /STRUCTURES

HELP, ASL, /STRUCTURES

 

여기서 TOT에 관한 출력 내용을 보면 다음과 같습니다.

 

** Structure TEAM, 5 tags, length=112, data length=106:

   NAME            STRING    'Tottenham Hotspur'

   POINT           INT             38

   NAMES           STRING    Array[4]

   HEIGHTS         FLOAT     Array[4]

   GOALS           INT       Array[4]

 

그러면 이와 같이 TOT라는 구조체에 관한 자세한 내용을 보여줍니다. 여기서 맨 첫 줄을 보면 "5 tags"라는 문구가 보이는데, 이는 구조체 내 필드 갯수가 5개라는 뜻입니다. 용어상으로는 여기서는 태그(Tag)라고 하는데 제가 지금까지 얘기한 필드(Field)와 동일한 개념입니다. 그리고 만약 이러한 필드들의 개수만 따로 뽑아내고자 할 경우에는 다음과 같이 N_TAGS 함수를 사용하면 됩니다.

 

PRINT, N_TAGS(TOT)

 

그러면 5라는 값이 출력될 것입니다. 그리고 구조체 내 필드들 각각의 명칭을 확인하려면 다음과 같이 TAG_NAMES 함수를 사용하면 됩니다.

 

PRINT, TAG_NAMES(TOT)

 

그러면 다음과 같이 모든 필드들의 이름이 출력될 것입니다.

 

NAME POINT NAMES HEIGHTS GOALS

 

그리고 앞서 익명 구조체와 기명 구조체에 관하여 언급을 했는데요. 통상적으로는 익명 구조체를 사용해도 충분합니다. 기명 구조체를 사용할 필요가 있는 경우는 앞서 설명한 바와 같이 동일한 형태의 구조체들을 복제해야 할 경우 정도라고 봐도 됩니다. 따라서 애초에 다음과 같이 내부 이름에 대한 정의를 생략하고 익명 구조체의 형태로 정의하여 사용해도 큰 지장은 없을 것 같습니다.

 

MNC = {name:'Manchester City', point:71, $
  names:STRARR(4), heights:FLTARR(4), goals:INTARR(4)}

 

물론 이렇게 익명 구조체로 생성할 경우에는 이를 활용하여 동일한 형태의 또 다른 구조체들을 복제하는 것은 불가능합니다.

 

그러면 구조체에 관한 소개는 대략 이 정도로 마무리합니다. 혼합형 자료형으로서 지금까지 소개된 구조체, 리스트, 해쉬에 관해서 잘 알아두면 IDL 프로그래밍 작업에 있어서 더 많은 도움이 될 것입니다.

 

 

* 이 내용은 지난 2021년에 올렸던 게시물의 내용을 일부 수정하여 다시 새롭게 올리는 내용입니다. 따라서 기존의 게시물은 이번 내용으로 대체되었습니다.

 

* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.

LIST

'IDL > Data Type & Format' 카테고리의 다른 글

해쉬(Hash) 자료형에 관하여  (1) 2025.06.10
리스트(List) 자료형에 관하여 [2]  (2) 2025.06.05
리스트(List) 자료형에 관하여 [1]  (0) 2025.06.04
ISA 함수의 활용  (0) 2025.06.02
TYPENAME 함수의 활용  (0) 2025.05.29