본문 바로가기

지식/자료구조

[자료구조] 구조체와 공용체 (Structures and Unions)

반응형

 

 

이번에는 구조체와 공용체에 대해서 알아보겠습니다.

<Structures>

먼저 구조체는 데이터 요소들의 집합이라고 할 수 있습니다. 각각의 데이터 요소들은 타입과 변수의 이름을 통해 구별됩니다.

 

이해를 돕기 위해 예를 먼저 들어보겠습니디.

struct {
	char name[10];
    	int age;
        float salary;
} person;

 

위의 구조체는 현재 이름이 person이고 3개의 fields를 가진다고 말합니다.

또한 이때 구조체의 크기는 fields의 크기의 합입니다.

여기서는 char: 10byte, int:  4byte, float: 4byte 이므로 18byte가 구조체의 크기가 됩니다.

 

구조체의 field에 접근할때는 . 이라는 operator를 사용합니다. 

strcpy(person.name, "james");
person.age = 10;
person.salary = 35000;

 

이때 유념할 점은 구조체 멤버 중 문자열을 입력하고 싶다묜 strcpy 함수를 사용해야한다는 것입니다.

 

우리는 구조체 데이터 타입으로 구조체 변수를 선언할 수 도 있습니다.

선언 방법은 다음과 같습니다.

struct person p1, p2;

 

struct를 써주고 구조체의 이름을 써주고 사용할 변수의 이름을 작성해주면 됩니다.

또한 이 변수를 통해 구조체 멤버에 접근할 수 있습니다. 

p1.age = 100;
p2.age = 50;

 

각각의 구조체 변수마다 자기만의 fields를 가지므로 위와 같이 사용할 수 있게됩니다.

 

구조체를 선언하는 방법은 또 한 가지가 더 있습니다.

typedef struct {
	char name[10];
	int age;
	float salary;
} humanbeing

 

이렇게 선언했을 때는 다음과 같이 구조체 변수를 만들 수 있습니다.

humanbeing person1, person2;

 

간단한 예시를 통해 더 깊게 알아보겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FALSE 0
#define TRUE 1

typedef struct {
  char name[10];
  int age;
  float salary;
} humanBeing;

int humans_equal(humanBeing, humanBeing);

void main() {

  humanBeing person1, person2;
  int rv;
 
  strcpy(person1.name, "James");
  person1.age = 10;
  person1.salary = 35000;

  strcpy(person2.name, "James");
  person2.age = 10;
  person2.salary = 35000;

  if(humans_equal(person1, person2))
    printf("The two human beings are the same.\n");
  else
    printf("The two human beings are NOT the same.\n");
}
  
int humans_equal(humanBeing person1, humanBeing person2) {
  /* returns TRUE if person1 and person2 are the same human being, 
     otherwise return FALSE */
  if(strcmp(person1.name, person2.name))
    return FALSE;
  if(person1.age != person2.age)
    return FALSE;
  if(person1.salary != person2.salary)
    return FALSE;
  return TRUE;
}

 

위 코드는 두 구조체 변수를 선언한 뒤 이름과 나이 급여에 모두 같은 값을 입력한 상황이며 humans_equal을 통해 두 구조체 변수의 3개의 fields가 서로 같은 값을 가진다면 같은 사람이라는 메세지를 출력하도록 하였습니다. 

구조체의 사용은 어렵지 않습니다.

 

또한 구조체를 선언할 때 구조체 안에 구조체를 선언할 수 있습니다.

typedef struct {
  int month;
  int day;
  int year;
} date;

typedef struct {
  char name[40];
  int age;
  float salary;
  date dob;
} humanbeing;

 

접근 또한 위에서 .을 통해 접근했던 방법 그대로 사용합니다.

구조체 안에서 다른 구조체를 변수로 사용할 수 있었는데 자기 자신도 사용이 가능할까요? 옙 가능합니다!

이를 자기 참조 구조체(Self -Referential Structures)라고 합니다.

struct list
{
  char data;
  struct list *link;
};

...

struct list item1, item2, item3;
item1.data = 'a';
item2.data = 'b';
item3.data = 'c';
item1.link = item2.link = item3.link = NULL;
item1.link = &item2;
item2.link = &item3;

 


<Unions>

공용체는 메모리 공간을 공유하는 fields입니다. 오직 1개의 filed가 프로그램이 돌아가는 동안 활성화됩니다.

typedef struct {
  int month;
  int day;
  int year;
} date;

typedef struct {
  enum tagField {pitcher, hitter} role;
  union {
    int SO;
    int HR;
  } u;
} playerType;

typedef struct {
  char name[40];
  int age;
  float salary;
  date dob;
  playerType playerInfo;
} baseballPlayer;

 

현재 playerType 구조체 안에 공용체가 선언되어 있는 것을 볼 수 있습니다. 여기서 다음과 같이 구조체를 사용한다고 하겠습니다.

baseballPlayer person1, person2;

person1.playerInfo.role = pitcher;
person1.playerInfo.u.SO = 163;

person2.playerInfo.role = hitter;
person2.playerInfo.u.HR = 24;

person1, person2 구조체 변수가 각각 공용체에 접근하여 공용체 내부의 변수를 사용하는 것을 볼 수 있습니다. 만약 여기서 다음과 같이 person1의 접근을 달리하면 출력하면 어떤 값이 나올까요??

person1.playerInfo.role = pitcher;
person1.playerInfo.u.SO = 163;
person1.playerInfo.u.HR = 24;

...

printf("%d\n", person1.playerInfo.u.SO)
printf("%d\n", person1.playerInfo.u.HR)

다음과 같이 작성후 printf문을 통해 확인해 본다면 두 결과 모두 24가 나온다는 것을 확인할 수 있습니다. 공용체는 자신이 가지는 여러개의 fields 중 한개의 field만 사용하기 때문에 가장 나중에 초기화 된 person1.playerInfo.u.HR의 값을 가지게 됩니다. 또한 person1.playerInfo.u.SO이 출력이 되는 이유는 이름만 다른 SO와 HR의 주소가 같기 때문에 person1.playerInfo.u.SO을 출력하더라도 person1.playerInfo.u.HR의 값이 나오게 되는 것입니다.

반응형