62 – 자기 참조 구조체

자기 참조 구조체란 다음과 같이 자기 자신의 구조체를 가리키는 포인터를 맴버로 하는 구조체이다. 자기 참조 구조체는 같은 유형의 구조체를 서로 연결해 관리하고자 할 때 이용된다. 이러한 구조를 “연결 리스트”라고 한다.

struct car
{
char name[10];    //차량 이름
int year;                // 연식
double fuel;         // 연료량
struct car *other;  // 자기 참조
};

아래의 예시를 보도록 하자. 이럴 경우에, first의 next가 second를, second의 next가 third를 가리키는 형태로 이어져 있는 것이다.

스크린샷 2017-04-21 오후 4.36.52

61 – 중첩 구조체

구조체를 정의할 때 다른 구조체의 맴버로 사용할 수 있는데, 이를 중첩 구조체라고 한다. 앞에서 봤던 자동차의 예제에서 문의 크기를 추가하고자 한다.

struct car
{
char name[10];    //차량 이름
int year;                // 연식
double fuel;         // 연료량
int left_door;       // 왼쪽 문 크기
int right_door;    //오른쪽 문 크기
int back_door;    //뒷문 크기
};

이런 식으로 구성할 때, door에 대한 맴버가 3개이기 때문에 이 맴버를 묶어서 다시 하나의 구조체로 만들고, 이 구조체를 하나의 맴버로 이용할 수 있다. 즉, 문에 대한 맴버 3을 가지고 먼저 구조체를 만든 후, 해당 구조체를 맴버로 만들면 된다.

struct size_of_door {
int left_door;
int right_door;
int back_door
};
struct car {
char name[10];
int year;
double fuel;
struct size_of_door size;
};

이 때, 주의해야 할 것이 있는데, 중첩 구조체는 그 구조체 자신을 맴버로 할 수는 없다

60 – 구조체

구조체는 서로 다른 데이터형의 변수들을 하나로 묶어 놓은 모임으로, 복잡한 데이터를 다루는 데 편리하다. 예를 들어, 차량 관리 프로그램을 작성할 경우에 각 차량에 대한 정보를 각각 관리하는 것보다 이 정보를 하나로 묶어서 관리하면 더 편리한데, 이 때 사용할 수 있는 것이 구조체이다. 차량에 대한 구조체를 구성한다고 할 때, 아래와 같은 예시대로 할 수 있다. 이름과 연식, 연료량을 묶어서 정의하였다.

struct car
{
char name[10];    //차량 이름
int year;                // 연식
double fuel;         // 연료량
};

struct는 구조체를 만들기 위해 바드시 필요한 부분이고, car는 태그 이름이다. 그리고 이 구조체는 name, year, fuel 세 개의 맴버로 이루어져 있다. 이 맴버들은 사용자가 정의한 새로운 형태의 데이터형이다. 그리고 이 새로운 데이터형인 struct car형의 변수를 선언하는 방법은 다음과 같다. 집앞에 있는 차량이 보여서 그걸로 예시를 만들어보았다.

struct car sonata;

이렇게 되면 sonata라는 이름의 변수에는 name, year, fuel을 내부에 가지고 있는 구조로 이루어져있다.

sonata -> [ name, year, fuel ]

이 구조체도 정의와 변수 선언을 동시에 할 수 있는데, 정의부의 제일 마지막에 변수명을 적어줌으로써 선언이 된다.

struct car
{
char name[10];    //차량 이름
int year;                // 연식
double fuel;         // 연료량
} sonata;     //변수 선언

또한 구조체를 정의할 때 태그 이름을 지정하지 않아도 된다. 그러나 이러한 구조체형은 이후의 선언을 할 수 없게 되는 문제점을 가지게 된다.

그리고 typedef를 사용하면 데이터형 struct를 car라는 이름으로 부르겠다는 것을 의미하며, 구조체형 이름의 길이가 짧아지는 장점이 생긴다. 이 때에는 구조체의 태그 이름을 생략해도 아무 문제가 발생하지 않는다. typedef에 대해서는 더 자세히 설명할 기회가 있다.

typedef struct
{
char name[10];    //차량 이름
int year;                // 연식
double fuel;         // 연료량
} car;                         //car라는 타입이 생성됨.

…..

car sonata;     //변수 선언 시 구조체의 이름이 짧아짐

만약, 구조체형 변수 sonata와 year 맴버에 2003을 저장하려면 도트(.)를 이용하여 접근한다.

sonata.year = 2003;

이렇게 맴버를 이용하는 것을 ‘맴버로 접근한다’라고 하며, 읽고 쓰는 데 이용된다.

구조체의 구성을 예시로 확인하기로 하겠다.

구조체형 변수도 일반 변수처럼 선언할 때 초기화 할 수 있으며, 배열 변수를 초기화하는 것와 유사하게 진행하면 된다.

struct car sonata = {
“SONATA”.
2003,
77.7
};

다른 구조체형일 경우에는 불가능하지만 동일한 구조체형의 변수들간에는 직접 복사 또한 가능하다. 바로 위에 sonata 외에도 동일한 차량으로 sm5를 만들어서 복사하고자 하면, 아래의 코드가 추가될 것이다.

struct car sm5;
sm5 = sonata;           //복사됨