본문 바로가기

C++ 일기

14. 사용자 정의 자료형 struct (구조체)

변수를 선언함에 있어, 서로 같은 이름의 변수. 즉, 같은 의미를 같는 변수를 여러번 선언할 때가 있다.

예를들어, 플레이어와 몬스터의 전투를 구현할 때, 플레이어와 몬스터는 각각 체력과 공격력 등, 같은 개념을 가지고 있다.

이럴 때, 우리는 monHp, playerHp 등 변수의 이름을 바꾸어 선언하였다.

이렇게 같은 개념을 공유하는 변수를 선언할 때 사용할 수 있는 것이 사용자 정의 자료형 struct이다.

여러개의 변수를 묶어서 하나의 데이터 단위로 정의하는 것을 뜻하며, 관련있는 데이터를 묶어서 표현할 필요가 있을 때

사용한다.

#include<iostream>

struct Unit
{
   int hp;
   int atk;
   int level;
   void PrintHp(int hp);
};

int main()
{
   Unit player;
   Unit mon;
   player.hp = 100;
   player.atk = 10
   mon.hp = 50;
   mon.atk = 5;
}

사용자 정의 자료형의 선언은 위와 같다. 편의를 위해 앞으로 구조체라고 하겠다.

먼저, 구조체의 이름을 정한다.

같은 개념을 공유하는 개체들의 공통점을 잘 표현할 수 있는 이름으로 선언하는 것이 좋다.

앞에서 설명한 플레이어와 몬스터의 전투를 가정했을 때, 나는 Unit이라는 이름으로 선언하였다.

그 후, 중괄호 안에 구조체가 가질 변수들을 선언한다. 이 때 구조체 안의 변수들은 멤버변수라고 부른다.

마지막으로는 세미콜론으로 구조체의 선언을 마무리짓는 것을 잊지말아야 한다.

이렇게 선언된 구조체는 main함수를 포함한 다른 함수에서 사용할 수 있다.

가장 먼저, 구조체를 이름과 함께 선언한다. 해당 구조체는 구조체 내의 멤버변수를 모두 가진다.

그 후, 해당 구조체의 이름과 점(.)을 찍어 구조체를 참조한다.

점을 찍으면, 구조체 안에 있는 멤버변수들이 나열되어 참조된다.

그 후, 참조된 구조체 안의 멤버변수를 정하고, 해당 값을 위처럼 초기화해줄 수 있다.

 

 

 

 

 

위에서는 구조체의 멤버변수 선언과 초기화에 대해 알아보았다.

하지만 구조체에는 변수 외에도 함수를 가질 수 있다. 이를 멤버함수라고 부른다.

#include<iostream>

struct Unit
{
   int hp;
   int atk;
   int level;
   void PrintHp(int hp);
};

Unit LvUp(Unit unit);

int main()
{
   Unit player;
   Unit mon;
   player.hp = 100;
   player.atk = 10
   mon.hp = 50;
   mon.atk = 5;
   
   player.PrintHp();      // 출력값 : 100
   player.LvUp(player);   // player의 hp, atk, level이 오름
   mon.LvUp(mon);      // mon의 hp, atk, level이 오름
}

void Unit::PrintHp(hp)
{
   std::cout << hp;
}

Unit LvUp(Unit unit)
{
   unit.hp += 50;
   unit.atk += 10;
   unit.level++;
   return unit;
}

구조체가 갖는 함수를 멤버함수라고 하는데, 선언을 구조체 안에서 하고 정의를 해주면 된다.

멤버함수는 선언을 구조체 안 혹은 밖에서, 정의를 안 혹은 밖에서 해주어야 하며

멤버함수를 밖에서 선언 혹은 정의할 경우, 멤버함수의 이름 앞에 구조체이름:: 으로 범위 지정 연산자를 사용해야한다.

위에서는 멤버함수를 구조체 안에서 선언하고, 밖에서 정의하였으며,

정의된 멤버함수의 이름 앞에 Unit::PrintHp라고 범위 지정 연산자를 통해 정의하였다.

 

 

또, 구조체를 매개로 하는 함수를 사용할 수도 있는데, 위의 Unit LvUp함수가 이에 해당된다.

이 때는 함수의 자료형은 구조체로 선언한다. 위에서는 Unit을 자료형으로 선언하였다.

그 후 함수를 정의하면 해당 구조체의 멤버변수에 접근할 수 있다.

매개변수를 구조체로 설정했기 때문에, 함수를 호출할 때마다 다른 구조체를 매개변수로 전달해,

구조체마다 각기 다르게 초기화된 멤버변수의 값을 조절하는 것이 가능하다.

위에서는 mon의 LvUp함수와 player의 LvUp 함수에 mon과 player로 다른 매개변수를 넣었기 때문에,

mon.LvUp은 mon의 atk, hp, level이 상승하고, player.LvUp은 player의 atk, hp, level이 각각 상승한다.

 

 

 

구조체의 선언과 멤버변수 초기화에는 아래와 같은 방법도 있다.

#include<iostream>

struct Unit
{
   int hp;
   int atk;
   int level;
};

int main()
{
   Unit mon[3] =
   {
      { 50, 5, 3 },
      { 30, 3, 1 },
      { 100, 10, 5 }
   };
   Unit player = { 100, 10, 1 };
}

구조체를 선언할 때는 위와 같이 배열로도 선언이 가능하다.

구조체 배열을 선언할 때에는 서로 굉장히 유사한 개체들이 여럿 필요할 때 선언할 수 있겠다.

예를들어 구조체 배열로 선언했는데, 플레이어와 몬스터가 서로 배열로 묶이면 후에 사용이 곤란해질 수 있다.

그리고, 배열로 선언하는 것 외에도 멤버변수 초기화를 선언과 동시에 위처럼 해줄 수 있다.

이는 배열이 아닐 때도 마찬가지이며 위의 player 선언과 같이 선언하면 된다.

 

 

위에서 선언하자마자 멤버변수를 초기화 했던 것을 보면, 구조체는 여러 변수들을 저장하는 배열인 것 같다.

이는 확실하지 않지만, 배열의 초기화와 구조체의 멤버변수 초기화의 구조가 동일하기 때문에 그렇게 생각했다.

구조체는 여러 자료형들을 하나의 배열에 저장한 모양이고,

구조체의 배열은 그럼 배열들을 저장한 배열이라는 뜻이 된다.

이용자(사람)의 시선에서는 굉장히 복잡하고 한 번에 머리에 잘 들어오지 않는 구조이지만,

컴퓨터가 연산할 때는 그러한 방식이 더 효율적이거나, 혹은 아무런 의미가 없을 지도 모르겠다.

'C++ 일기' 카테고리의 다른 글

16. Call by Reference, Call by Value, Call by Reference  (0) 2024.02.27
15. 포인터  (0) 2024.02.27
13. 난수 발생  (0) 2024.02.27
12. 열거형 타입 enum  (0) 2024.02.26
11 - 2. 함수 오버로딩  (2) 2024.02.26