프로그래밍 C언어

구조체 (Structure)

게임첫걸음 2024. 8. 20. 16:58
#include <stdio.h>
#include <malloc.h>

struct SCharacter		// 구조체 선언! (Structure Declaration)
{
	// 멤버 변수(Member Variablese)
	// 구조체 패딩(Structure Padding): 부족한 메모리를 채워주는 거
	char lv;			// 1byte	//alt 누르고 방향키 누르면 그 코드가 이동
	int hp;				// 4byte
	short mp;			// 2byte	
	int exp;			// 4byte
	// int arr[3];		// 배열도 됨. 이건 12byte
	int equip[3];
};

typedef struct SCharacter SChar;//SCharacter를 SChar로 표현한다는 뜻
typedef unsigned int HP;		//HP를 다룰 때 사용할 것으로 unsigned를 붙이면 모든 HP 코드들은 unsigned가 붙는 형태임.

typedef struct _Char
{
	int lv;
} Char;

struct _Char sChar;
Char sChar2;


void main()
{
	// 구조체(Structure)		//배열과 다른점은 자료형을 다른 점: 각 멤버 변수의 자료형을 다르게 사용할 수 있음
	// 사용자 정의 자료형
	// 기본 자료형(Primitive Type): 구조체가 재료
	struct SCharacter player = { 1, 50, 10, 5 };
	struct SCharacter monster;

	player.hp = 100;	// . 점을 찍으면 다룰 수 있는 구조체 선언된 멤버 변수들이 나타남.
	player.lv = 5;

	printf("player.lv: %d (%p)\n", player.lv, &player.lv);
	printf("player.hp: %d (%p)\n", player.hp, &player.hp);
	printf("player.mp: %d (%p)\n", player.mp, &player.mp);
	printf("player.exp: %d (%p)\n", player.exp, &player.exp);

	printf("SCharacter Size: %d byte\n", sizeof(struct SCharacter));

	////////////////////////////////////////////////

	printf("\n");

	SChar monsters[3] = 
	{ 
		(1, 2, 3, 4),
		(1, 2, 3, 4),
		(1, 2, 3, 4)
	};
	monsters[1].hp = 1000;

	HP hp = 10;

	///////////////////////////////////////////////

	SChar* dChar = (SChar*)malloc(sizeof(SChar));

	dChar->lv = 100;	// 동적 배열은 ->로 접근

	if (dChar != NULL)
	{
		free(dChar);
		dChar = NULL;
	}

	/////////////////////////////////////////////

	SChar sour = { 11, 22, 33, 44, { 7, 3, 9 } };
	SChar dest = sour;

	printf("dest.lv: %d\n", dest.lv);
	printf("dest.hp: %d\n", dest.hp);
	printf("dest.mp: %d\n", dest.mp);
	printf("dest.exp: %d\n", dest.exp);
	for (int i = 0; i < 3; ++i)
	{
		printf("dest.equip[%d]: %d\n", i, dest.equip[i]);
	}

	printf("\n");
	dest.equip[1] = 40;
	printf("dest.equip[1]: %d\n", dest.equip[1]);
	printf("sour.equip[1]: %d\n", sour.equip[1]);
	return;
}

 

이번 글은 구조체입니다. 구조체는 사용자 정의 데이터를 하나의 범주로 묶는데 사용합니다. 그 데이터들을 멤버 변수라고 표현하고 그들의 자료형은 제각각 설정할 수 있습니다. 

 

struct SCharacter // 구조체 선언! (Structure Declaration)
{
      // 멤버 변수(Member Variablese)
      // 구조체 패딩(Structure Padding): 부족한 메모리를 채워주는 거
      char lv;          // 1byte //alt 누르고 방향키 누르면 그 코드가 이동 
      int hp;            // 4byte 
      short mp;       // 2byte
      int exp;          // 4byte
      int equip[3];   // 4*3= 12byte
};

주석에 적힌 것은 각 자료형에 따른 크기인데 여기서 구조체는 구조체 패딩(Structure Padding)이라는 것이 적용됩니다. 위의 구성 멤버 변수대로 SCharacter 구조체 전체 크기를 출력하면 28byte가 됩니다. 그 이유에 대해 설명하겠습니다.

구조체 패딩 (Structure Padding)

 구조체 패딩은 데이터의 메모리 배치를 최적화하기 위해 사용되는 기술로 위에서 밑 방향으로 큰 크기를 기준으로 위의 자료형 크기에 +되는 형태입니다. 그림에 따라 char는 1byte에서 4byte로 바뀌고 short는 2byte에서 4byte로 변환되고, int의 3 크기인 equip은 4*3으로 12byte를 할당받습니다. 이에 따라 16+12로 28byte가 출력됩니다. 데이터의 자료형 위치가 어디인지에 따라 크기가 변화합니다.

 

<typedef> (별칭)

typedef struct SCharacter SChar;//SCharacter를 SChar로 정의한다는 뜻
typedef unsigned int HP; //HP를 다룰 때 사용할 것으로 unsigned를 붙이면 모든 HP 코드들은 unsigned가 붙는 형태임.

typedef struct _Char       // int lv이라는 멤버를 가진 _Char 구조체를 Char로 정의합니다.

{
     int lv;
} Char;

 

struct _Char sChar;        // _Char 를 sChar로 정의합니다.
Char sChar2;                  // Char를 sChar2로 정의합니다.

 

typedef는 구조체의 별칭을 정할 때 사용하는 용어로 주석으로 설명을 완료하겠습니다. 이에 따라 sChar2는 _Char 구조체와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void main()
{
    // 구조체(Structure)        //배열과 다른점은 자료형을 다른 점: 각 멤버 변수의 자료형을 다르게 사용할 수 있음
    // 사용자 정의 자료형
    // 기본 자료형(Primitive Type): 구조체가 재료
    struct SCharacter player = { 150105 }; // SCharacter 구조체를 가진 player 데이터 4개
    struct SCharacter monster; // SCharacter 구조체를 가진 monster 데이터 4개
 
    player.hp = 100;    // player hp를 100으로 초기화
    player.lv = 5; // player lv를 5로 초기화
 
    printf("player.lv: %d (%p)\n", player.lv, &player.lv); // 5 (위치값)
    printf("player.hp: %d (%p)\n", player.hp, &player.hp); // 100 (위치값)
    printf("player.mp: %d (%p)\n", player.mp, &player.mp); // 10 (위치값)
    printf("player.exp: %d (%p)\n", player.exp, &player.exp); // 5 (위치값)
 
    printf("SCharacter Size: %d byte\n"sizeof(struct SCharacter)); // 28byte
 
    ////////////////////////////////////////////////
 
    printf("\n");
 
    SChar monsters[3= // typedef로 SCharacter 구조체의 monsters 배열
    { 
        (1234),
        (1234),
        (1234)
   }; // 각 4개의 요소에 해당하는 값들 초기화
    monsters[1].hp = 1000; // monsters의 두 번째 요소의 hp값을 1000으로 초기화
 
    HP hp = 10;
 
    ///////////////////////////////////////////////
 
    SChar* dChar = (SChar*)malloc(sizeof(SChar));
//SChar 포인터 변수 dChar에 sizeof(SChar) 만큼의 메모리 크기 할당
 
    dChar->lv = 100;    // 동적 배열은 ->로 접근
 
    if (dChar != NULL) // NULL 예외처리
    {
        free(dChar); // dChar변수 주소값 해제
        dChar = NULL; // dChar를 NULL로 처리
    }
 
    /////////////////////////////////////////////
 
    SChar sour = { 11223344, { 739 } }; //SCharacter 구조체 sour 구성
    SChar dest = sour; //SCharacter 구조체 dest는 sour과 같음
 
    printf("dest.lv: %d\n", dest.lv); //dest.lv: 11
    printf("dest.hp: %d\n", dest.hp); //dest.hp: 22
    printf("dest.mp: %d\n", dest.mp); //dest.mp: 33
    printf("dest.exp: %d\n", dest.exp); //dest.exp: 44
    for (int i = 0; i < 3++i) // dest.equip[0~2]까지 출력위한 반복문
    {
        printf("dest.equip[%d]: %d\n", i, dest.equip[i]); //dest.equip[0]: 7 / [1]:3 / [2]: 9
    }
 
    printf("\n");
    dest.equip[1= 40; //dest.eqiup[1]: 40 초기화
    printf("dest.equip[1]: %d\n", dest.equip[1]); //dest.equip[1]: 40
    printf("sour.equip[1]: %d\n", sour.equip[1]); //sour.equip[1]: 3
    return;
}
cs

 위는 main함수에 대한 주석 설명입니다. 동적 배열은 프로그램이 가동되며 계속해서 할당된 메모리의 크기 또는 값이 유동적으로 바뀌는 배열입니다. 게임에서 자주 다루는 것이기 때문에 잘 알아두는 것이 좋을 것 같습니다.

 

'프로그래밍 C언어' 카테고리의 다른 글

상수 열거형 (Enumeration)  (0) 2024.08.20
공용체 (Union)  (0) 2024.08.20
비트 단위 연산자 (Bitwise Operators)  (0) 2024.08.18
동적 메모리 할당 (Dynamic Memory Allocate)  (0) 2024.08.18
문자열 (String)  (0) 2024.08.16