2016. 2. 25. 13:10

기본적으로 많이 사용하는 형식의 데이터형만 기본 데이터로써 정의되고있고, 나머지는 프로그래머가 필요에따라 정의해서 사용할 수 있도록 만들수있습니다.


그래서 기본 데이터 형인 char, int, float, double등을 제공하고 나머지는 프로그래머가 배열, 포인터,구조체, 공용체, 혹은 typedef 같은 문법을 사용해 직접 정의 해서 사용합니다.


배열과 같은 무법으로 사용자 정의 데이터형을 만들게 되면 동일한 데이터 형만을 그룹지을 수 있습니다. 단순한 형태만 정의 가능하다는 단점이 있지만, 이를 보완하기 위해 만들어 진것이 구조체 입니다.


구조체는 서로 다른 데이터형을 하나의 데이터로 군집화 하여 사용 할 수 있도록 하는 사용자 정의 데이터 형입니다.


1. 구조체 정의하기

 

구조체를 정의 할 때에는 다음과 같이 사용합니다.


struct 구조체명 {

데이터형 변수명;

...

};

이렇게 선언된 구조체명이 새로 쓸수있는 데이터형의 이름입니다. 즉, int char처럼 사용가능합니다.


구조체는 struct 키워드를 앞에 명시한 다음에 사용할 구조체명을 적어서 정의합니다. 이 때 구조체

     내부를 구성하는 데이터는 미리 정의되어 있어야 하며, 각 데이터는 세미콜론(" ; ") 키워드로 

분리해야합니다. 

예를 들어 이름, 나이, 키, 몸무게와 같은 인적사항을 저장하는 People 이라는 구조체를 정의하면 다음과 같습니다.


1
2
3
4
5
6
7
 
    struct People {
        char name[20];
        int age;
        double height;
        double weight;
    };
cs

    위에서도 말했듯이 구조체 내부의 데이터는 미리 정의된 데이터형이여야하기 때문에 char, int, double

    등과 같은 기본 데이터형 외에 다른 구조체나 사용자가 따로 정의한 데이터형을 사용하고 싶으면

    이 구조체보다 앞서 정의되어 있어야합니다.

 

    일반적이지는 않지만 한번만 선언해서 사용하는 경우 아래와 같이 구조체명을 생략해서 사용하는 경우도 있습니다.

즉, 구조체를 정의함과 동시에 data 라는 변수를 선언하여 사용하기 때문에 이 데이터형을 다시 사용할 필요가 없다면 구조체명도 필요없기 때문에 생략 가능합니다.

 

 

1
2
3
4
5
6
    struct {
        char name[20];
        int age;
        double height;
        double weight;
    } data;
cs

 

 

2. 구조체 사용하기

 

    정의된 구조체는 구조체명을 이용하여 변수를 선언하듯이 선언해주면 되는데, C 언어에서는 구조체를

    이용하여 변수를 선언할 때에는 반드시 구조체명 앞에 "struct" 키워드를 붙여주어야합니다.

 

    // People 구조체를 사용하여 data 변수를 선언한다.

    struct People data;

 

    C++ 언어로 구조체를 선언할 때에는 struct 키워드를 생략하여 선언할 수 있지만 C 언어의 경우에는

    구조체를 선언할 때마다 struct 키워드를 명시해야 하기때문에 (굉장히 불편합니다.)

해결법으로는 아래와 같이 typedef 명령어를 이용하여 구조체를 또다른 데이터 타입으로 정의하여 사용하기도 합니다.

 

    typedef struct People PEOPLE;

 

    이렇게 선언하면 C 언어에서도  People 구조체를 사용하여 변수를 선언할때 struct 키워드를

    적지 않게되어 좀더 편리하게 사용할수 있습니다.

 

    PEOPLE data;  // struct People data;

 

    하지만, 구조체 정의 따로 typedef 정의 따로 사용하는 방식이 프로그램을 이해하기에 불편할수도

    있기 때문에 이것을 아래와 같이 한번에 사용하여 구조체를 정의하기도 합니다.

 

1
2
3
4
5
6
7
8
 
 // struct people { ... } 구조체를 PEOPLE 이라는 데이터형으로 정의한다.
    typedef struct People{
        char name[20];
        int age;
        double height;
        double weight;
    } PEOPLE;
cs

 

최근에는 C++ 를 사용하는 사람들이 많아짐에따라 struct 가 생략가능해지면서 typedef 을 사용하는 형식도 점차 줄어들고 있습니다.    (Class가 있으니..)

   

구조체로 선언한 데이터형도 기본데이터형(char, int, ...)과 동일한 데이터 형이기 때문에 변수 선언 배열, 포인터 문법을 아래와 같이 그대로 사용할수 있습니다.

 

PEOPLE data;      // 일반 변수

PEOPLE list[20];  // 배열

PEOPLE *p;         // 포인터

 

이렇게 선언된 구조체 변수는 아래의 코드처럼 구조체의 요소에 접근할 때에는 " . " 를 이용하여 구조체의 "변수명.요소명" 과 같은 형식을 사용합니다.

     

1
2
3
4
5
6
PEOPLE one;
 
    strcpy(one.name, "운영진");
    one.age = 23;
    one.height = 179.9;
    one.weight = 70;
cs

 

3. 구조체의 크기와 메모리 배열 ( struct member alignment )

 

구조체의 크기는 일반적으로 구조체를 구성하는 데이터형의 크기를 합산한 값입니다.


    Windows 32비트 운영체제는 레지스터의 크기, 데이터 버스의 크기, 데이터 처리 단위, 포인터의 크기

    등이 모두 4 바이트로 되어 있어서 해당 크기로 연산하고, 처리하는 것이 속도가 더 빠릅니다. 그래서 

    컴파일 옵션에 따라서 구조체를 해석할때 그 배열을 짝수 또는 4의 배수로 재구성하는 작업

    수행하기 때문에 실제로 구조체가 구성되는 것이 조금 다를 수 있습니다.

 

1
2
3
4
5
6
7
typedef struct Test {
        char a;       // 1 바이트의 데이터 크기를 가짐
        int b;          // 4 바이트의 데이터 크기를 가짐
        short int c;  // 2 바이트의 데이터 크기를 가짐
        int d;          // 4 바이트의 데이터 크기를 가짐
        char e;       // 1 바이트의 데이터 크기를 가짐
    } TEST;
cs

 

위와 같이 정의된 TEST 구조체를 선언하면 12 바이트의 메모리가 할당된다고 생각할 수도 있지만

구조체를 구성하고 저장하는 단위가 4 바이트이기 때문에 b 나 d 같은 4 바이트 이상의 크기를 가지는

변수가 4의 배수 주소 값에 위치하도록 아래와 같은 형태로 메모리가 사용되어 20 바이트의 메모리가 할당됩니다.

 

그렇기때문에 쓸데없는 메모리의 낭비를 막기 위해서는 아래와 같이 데이터를 구성하는 순서를변경하여 구조체를 정의하는 것이 좋습니다.

 

   

1
2
3
4
5
6
7
typedef struct Test {
        int b;          // 4 바이트의 데이터 크기를 가짐
        int d;          // 4 바이트의 데이터 크기를 가짐
        short int c;  // 2 바이트의 데이터 크기를 가짐
        char a;       // 1 바이트의 데이터 크기를 가짐
        char e;       // 1 바이트의 데이터 크기를 가짐
    } TEST;
cs

 

   

 

이처럼 구조체를 정의할 때 어떻게 배치하는가에 따라 구조체의 크기가 변경될 수 있기때문에 메모리를 낭비하지 않도록 주의해야합니다,

프로그래밍을 하다가 구조체의 크기를 명시해야하는 경우에는 수치 값이 아닌 sizeof 매크로를 사용하여 구조체의 크기를 반환받아 사용해야합니다. 

Posted by 시리시안