프로그래밍 언어/C

구조체(Structure)

gcreators 2024. 8. 20. 17:21

구조체란 복합 자료형 혹은 사용자 정의 자료형 이라고들 말한다

 

우리가 기존에 사용하던 int, double, char등은 기본 자료형(Primitive Type) 이라고 한다. 

 

구조체 선언(Structure Declaration)

 

struct 이름 { 내용 }

struct SCharacter
{
	int lv;
	int hp;
	int mp;
	int exp;
}

 

사용 예시

#include<stdio.h>

struct SCharacter
{
	int lv;
	int hp;
	int mp;
	int exp;
}

void main()
{
	struct SCharacter player = {1, 50, 10, 5};
    
    // . : 맴버 접근 지정자
    	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);
}

배열처럼 4byte의 크기씩 가지며 변수들을 활용 할 수 있는 것으로 보이지만

 

배열과 구조체가 다른점 : 자료형 배열은 같은 자료형을, 구조체는 다른 자로형들을 사용 할 수 있다.

struct SCharacter
{
    char lv;
    int hp;
    short mp;
    int exp;
}

 

구조체는 다음과 같이 여러 자료형들을 묶어서 사용 할 수 있는데

 

이렇게 되면 메모리에서는 용량이 어떻게 할당이 되는지가 문제가 될 것이다

 

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

char + int + short + int -> 1+4+2+4 = 11 이 나와야 할거 같지만 16byte가 나온다.

그리고 재미있는 것은

struct SCharacter
{
    char lv;
    short mp;
    int hp;
    int exp;
}

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

이렇게 char와 short를 붙이면 전체 크기가 12byte가 나온다.

 

이 두가지 경우를 그림으로 표현하면 이렇다

padding이란 남는 공간이라고 이해하면 된다.

 

구조체가 다음과 같은 크기를 가지게 되는데에는 두가지 규칙을 가지기 때문이다.

1.cpu 연산 속도의 영향

이는 int형처럼 운영체제의 영향을 받기에 4byte의 처리단위를 기준으로 크기를 정한다

그렇기에 구조체의 맴버당 기본적으로 4byte의 크기를 가지고 있지만

그 다음에 오는 구조체 맴버의 크기가 남는 공간인 padding에 들어갈 수 있는 경우 거기에 자동적으로 들어가게 된다

 

2. 가장 큰 맴버를 기준으로 크기가 정해진다

지금 같은 코드는 int형 4byte가 가장 큰 크기를 가지게 되지만

struct SCharacter
{
    char lv;
    short mp;
    int hp;
    double exp;
}

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

다음과 같은 경우 가장 큰 맴버인 double형 즉 8byte의 크기를 가지게 된다

여기서 char, short, int 형은 각 1,2,4 byte라 8byte보다 작으므로 그 공간에 다 들어간 뒤 1byte의 padding공간을 가지게 된다

따라서 저렇게 구성될 경우 구조체의 크기는 16byte가 된다

 

#include<stdio.h>
#include<malloc.h>

typedef struct _SChar
{
	int lv;
	int hp;
	int mp;
	int exp;
	int equip[3];
} SChar;

void main(){
    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]);
}

 

이렇게 구조체도 복사가 가능한 것을 확인 할 수 있다.

동적 할당 구조체

#include<stdio.h>
#include<malloc.h>

typedef struct _SChar
{
	int lv;
	int hp;
	int mp;
	int exp;
	int equip[3];
} SChar;

void main()
{

	SChar* dChar = (SChar*)malloc(sizeof(SChar));
    
    //동적할당 구조체 접근법
	dChar->lv = 100;
    
    //동적 할당 해제
    if (dChar != NULL)
	{
		free(dChar);
		dChar = NULL;
	}
    
}