struct 구조체명 {

자료형 멤버명;

}

구조체의 기본 구조 

---------------------------------------------------------------------------------------------

struct data {

char a;

int b;

}:

---------------------------------------------------------------------------------------------

구조체를 선언함과 동시에 변수 선언

struct data {

char a;

int b;

}: data_type_1; data_type_2;

---------------------------------------------------------------------------------------------

구조체 타입 data를 정의한 뒤에 data_type_1과 data_Type_2 선언

struct data {

char a;

int b;

}: 

struct data data_type_1; 

struct data data_type_2;

---------------------------------------------------------------------------------------------

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
#include <stdio.h>
 
struct data
{
        char a;
        int b;
};
 
int main()
{
        struct data data_type_var;
 
        printf("char : %lu Byte\n", (unsigned long)sizeof(char));
        printf("int : %lu Byte\n", (unsigned long)sizeof(int));
        printf("struct data : %lu Byte\n",(unsigned long)sizeof(struct data));
 
        data_type_var.a = 'A';
        data_type_var.b = 100;
 
        printf("data_type_var.a : %c\n",data_type_var.a);
        printf("data_tyoe_var.b : %d\n",data_type_var.b);
 
        return 0;
}
 
cs

struct 에서는 char를 4byte로 처리하기 때문에 struct data에서 4+4 = 8이 나오게된다.
소스 코드를 컴파일할 때 해당 구조체의 크기를 정렬하여 컴파일하기 떄문이다 
이를 구조체 멤버정렬(struct member alignment) 라고 한다 .
소스 코드를 컴파일 할 때 구조체 멤버 정렬이 발생하는 이유는 CPU에서 메모리에 접근 할 때 특정한 사이즈로 접근을 해야 더욱 속도가 빠르기 때문이다.
멤버 정렬을 하면서 정렬 사이즈 단위에 부족하면 부족한 해당 바이트 값만큼 패딩을 추가하여 정렬 사이즈를 맞춘다 ( 패딩 = 남은 공간을 채우는것)

( %lu = unsigned long 이라는 의미이며 ul로 쓰면 에러가 발생할 수 있다한다.)


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
 
#include <stdio.h>
 
struct data
{
        char a;
        int b;
}__attribute__((packed));
 
int main()
{
        struct data data_type_var;
 
        printf("char : %lu Byte\n", (unsigned long)sizeof(char));
        printf("int : %lu Byte\n", (unsigned long)sizeof(int));
        printf("struct data : %lu Byte\n",(unsigned long)sizeof(struct data));
 
        data_type_var.a = 'A';
        data_type_var.b = 100;
 
        printf("data_type_var.a : %c\n",data_type_var.a);
        printf("data_tyoe_var.b : %d\n",data_type_var.b);
 
        return 0;
}
cs

위 소스와 달라진 점은 struct(구조체)가 끝나는 시점에 __attribute__((packed));
를 추가해줬다는 것이다 . 의미는 구조체를 정의할때 패딩 없이 채운다는 의미이다.
리눅스 gcc환경에서 가능하고 윈도우(vc) 환경에서는 
#pragma pack(push, 1)
struct data{
    char a;
    int b;
}:
#pragma pack(pop)
를 추가한다

struct data 에서 char 1 int 4 를 해서 5 Byte가 출력되는것을 확인할 수 있다 

구조체 초기화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
struct data
{
        char a;
        int b;
        float c;
};
 
int main()
{
        struct data a ={'B'101 , 1.2};
 
        printf("a.a : %c, a.b: %d, a.c : %f\n" , a.a , a.b , a.c);
 
        return 0;
}
 
cs

---------------------------------------------------------------------------------------------비트 필드 

기본 자료형에서 가장 작은 char 형도 1바이트를 차지한다. 
그보다 더 작게 비트로 어떻게 선언할 수 있을까 ? 

struct 구조체에서 몇 비트를 사용할 것 인지 선언을 한다 
main() 내부에서 얼마나 큰 수 (10진수)를 사용할 것인지 

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
#include <stdio.h>
 
struct data
{
        unsigned char a:2;
        unsigned char b:2;
        unsigned char c:4;
};
 
int main()
{
        struct data a;
 
        a.a = 2;
        a.b = 1;
        a.c =1;
 
        printf("struct data : %lu\n" , (unsigned long)sizeof(struct data));
 
        printf("a.a : %d\n" , a.a);
        printf("a.b : %d\n" , a.b);
        printf("a.c : %d\n" , a.c);
 
        return 0;
}
 
cs

2^2 혹은 2^4 이상의 수를 주면 오버 플로우가 발생한다 

---------------------------------------------------------------------------------------------공용체 


공용체는 구조체와 비슷한 문법을 갖고 있고 형태도 비슷하지만 구조체와 달리 멤버들이 하나의 메모리 공간을 공유해서 사용한다는 점에서 다른 특징을 갖고 있다.

ex ) 구조체 = 선언되어 있는 자료형의 크기를 더한것이 구조체의 크기 
      공용체 = 선언되어 있는 멤버 중에서 가장 큰 메모리 공간을 차지하는 변수의 크기가 메모리의 크기가 됨.

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
 #include <stdio.h>
  2 
  3 union data
  4 {
  5         char a;
  6         int b;
  7 };
  8 
  9 int main(void)
 10 {
 11         union data data_type_var;
 12 
 13         printf("union data : %luByte\n",(unsigned long)sizeof(union data));
 14         printf("union data a : %luByte\n",(unsigned long)sizeof(data_type_var.a));
 15         printf("union data b : %luByte\n",(unsigned long)sizeof(data_type_var.b));
 16 
 17         data_type_var.b = 0x11223344;
 18 
 19         printf("data_type_var.a : %x\n" , data_type_var.a);
 20         printf("data_type_var.b : %x\n" , data_type_var.b);
 21 
 22         data_type_var.a = 0x55;
 23 
 24         printf("data_type_var.a : %x\n" , data_type_var.a);
 25         printf("data_type_var.b : %x\n" , data_type_var.b);
 26 
 27         return 0;
 28 }
 29 
 30 
 
cs

 

union data는 크기가 가장 큰 b의 4BYTE를 따라가고 있다 .

17행에서 data_type_var.b = 0x11223344;

를 선언하였고 var.a에서 44를 나타내는걸 보면 같은 메모리를 공유하고 있는 것을 확인 할 수 있다 .

22행에서 data_type_var.a = 0x55;

를 선언하였고 var.a 결과가 55 나왔다. 
var.b의 값이 11223355가 나왔고 같은 메모리를 공유하고 있는 것을 확인 할 수 있다.


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
#include <stdio.h>
 
struct data
{
        union {
                struct {
                        char data_a;
                        int data_b;
                };
 
                struct {
                        char a;
                        int b;
                };
        };
};
 
int main(void)
{
        struct data data;
 
        data.a = 1;
        data.data_b = 2;
 
        printf("data.data_a : %d\n", data.data_a);
        printf("data.data_b : %d\n", data.data_b);
 
        printf("data.a : %d\n", data.a);
        printf("data.b : %d\n", data.b);
 
        return 0;
}
 
cs

다른 구조체이지만 한 공용체 안에 들어있기 때문에 같은 메모리 공간을 공유하고있다.

그렇기 떄문에 서로 다른 변수 이름으로 같은 값을 갖게 된다 .


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
 
#include <stdio.h>
 
enum day {MON, TUE, WED, THU, FRI, SAT, SUN};
enum test {A=100,B=103,C};
 
int main()
{
        enum day d;
 
        d = MON;
 
        printf("MON : %d, TUE : %d, WED : %d, THU : %d , FRI : %d , SAT : %d , SUN : %d\n",MON,TUE,WED,THU,FRI,SAT,SUN);
 
        printf("A : %d , B : %d , C : %d\n" , A ,B ,C);
 
        switch(d)
        {
                case MON:
                     printf("Ang\n");
                     printf("\n");
                     break;
                case TUE:
                     break;
                case WED:
                     break;
                case THU:
                     break;
                case FRI:
                     break;
                case SAT:
                     break;
                case SUN:
                     break;
        }
        return 0;
}
 
cs



'c언어' 카테고리의 다른 글

구조체 배열 포인터 중얼-1  (0) 2016.08.10
void형 포인터  (0) 2016.08.09
조건부 컴파일  (0) 2016.08.08
정보 올림피아드 - 147  (0) 2016.08.03
정보 올림피아드 - 146  (0) 2016.08.02

+ Recent posts