typedef

typedef를 배우기 전에 다음의 코드를 살펴보자. 

<소스코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
struct point {
    int xpos;
    int ypos;
};
 
int main(void) {
    struct point pnt = { 23 };
    printf("[%d, %d]", pnt.xpos, pnt.ypos);
 
    return 0;
}
 
cs

9번 라인을 보면 struct point형 변수를 선언하기 위해 struct point pnt = {2, 3}; 으로 선언한 것을 볼 수 있다. 매번 struct를 사용하는 것은 불편하다. 그렇다면 int num = 10; 처럼 간단하게 할 수 있는 방법이 없을까? 있다. 바로 typedef를 사용하면 된다. 이를 다음의 소스코드와 이전의 소스코드를 비교하며 이해해보자.

<소스코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
typedef struct {
    int xpos;
    int ypos;
} Point;
 
int main(void) {
    Point pnt = { 23 };
    printf("[%d, %d]", pnt.xpos, pnt.ypos);
 
    return 0;
}
 
cs

두 코드의 실행결과는 모두 동일하며 3번 라인을 보면 struct 앞에 typedef 키워드가 있고 point라는 구조체 이름이 빠지고 구조체의 마지막에 Point라고 붙여진것을 볼 수 있다. 이를 통해 9번 라인에서 볼 수 있듯이 단순하게 Point pnt = {2, 3}; 으로 구조체 변수를 간단하게 생성하는 것을 볼 수 있다.


함수로의 구조체 변수 전달과 반환

기본 자료형과 마찬가지로 구조체 변수 역시 매개변수에 복사가 되거나 반환될 수 있다. 다음의 코드를 살펴보자.

<소스코드>

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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
typedef struct {
    int xpos;
    int ypos;
} Point;
 
void showPosition(Point pnt) {
    printf("[%d, %d] \n", pnt.xpos, pnt.ypos);
}
 
Point GetCurrentPosition(void) {
    Point cen;
    printf("pos를 입력하시오 : ");
    scanf("%d %d"&cen.xpos, &cen.ypos);
    return cen;
}
 
int main(void) {
    Point curPos = GetCurrentPosition();
    showPosition(curPos);
 
    return 0;
}
 
cs

<실행결과>

라인 9번에서 볼 수 있듯이 매개변수로 구조체 변수가 들어갔고 21번 라인에서 볼 수 있듯 반환값을 Point 변수 curpos에 대입하는것을 볼 수 있다. 또한 매개변수로 구조체의 포인터 변수도 들어갈 수 있다. 이를 통해 Call by reference도 할 수 있다. 이를 예시 코드를 통해 알아보자.

<소스코드>

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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
typedef struct {
    int xpos;
    int ypos;
} Point;
 
void OrgSynTrans(Point* pnt) {
    pnt->xpos = pnt->xpos * -1;
    pnt->ypos = pnt->ypos * -1;
}
 
void showPosition(Point pnt) {
    printf("[%d, %d] \n", pnt.xpos, pnt.ypos);
}
 
int main(void) {
    Point pos = { 7-5 };
    OrgSynTrans(&pos);
    showPosition(pos);
    OrgSynTrans(&pos);
    showPosition(pos);
    return 0;
}
 
cs

<실행결과>

9번 라인에서 볼 수 있듯이 함수의 매개변수로 구조체의 주소값을 넘겨서 원점 대칭하는것을 알 수 있다. 따라서 메인함수의 좌표값을 메인함수 외부에서 변경하는것을 볼 수 있다.

또한 구조체 변수 역시 구조체의 멤버로 포함될 수 있다. 이를 구조체의 중첩이라 한다. 다음의 소스코드를 확인하자.

<소스코드>

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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
typedef struct {
    int xpos;
    int ypos;
} Point;
 
typedef struct {
    Point cen;
    double rad;
} Circle;
 
void showCircleInfo(Circle * c) {
    printf("[%d, %d] \n", (c->cen).xpos, (c->cen).ypos);
    printf("radius: %g \n\n", c->rad);
}
 
int main(void) {
    Circle c1 = { {12}, 3.5 }; // 구조체가 중첩 됨
    showCircleInfo(&c1);
 
    return 0;
}
 
cs

<실행결과>

20번 라인에서 볼 수 있듯이 구조체가 중첩된 것을 알 수 있다.


UNION

구조체와 공용체(union)의 차이

typedef struct {

    int mem1;

    int mem2;

    double mem3;

} Sbox;

 

typedef union {

    int mem1;

    int mem2;

    double mem3;

} Ubox;

위의 Sbox, Ubox의 sizeof 연산을 해보면 각각 16 byte, 8  byte 인것을 확인할 수 있다.  이를 그림으로 표현하면 다음과 같다.

이 union은 하나의 메모리 공간에 둘 이상의 방식으로 접근할 수 있다는 특성이 있다.

 


Enum 열거형

enum을 설명하기 전에 먼저 다음의 소스코드를 보자.

<소스코드>

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
#include <stdio.h>
 
typedef enum {
    Do = 1, Re = 2, Mi = 3, Fa = 4, Sol = 5, La = 6, Ti = 7
} Syllable;
 
void Sound(Syllable sy) {
    switch (sy) {
    case Do:
        puts("도 입니다.");
        return;
    case Re:
        puts("레 입니다.");
        return;
    case Mi:
        puts("미 입니다.");
        return;
    case Fa:
        puts("파 입니다");
        return;
    case Sol:
        puts("솔 입니다.");
        return;
    case La:
        puts("라 입니다.");
        return;
    case Ti:
        puts("시 입니다.");
        return;
    }
}
 
int main(void) {
    Syllable tone;
    for (tone = Do; tone <= Ti; tone++)
        Sound(tone);
    return 0;
}
 
cs

<실행결과>

열거형은 연관이 있는 이름을 동시에 상수로 선언할 수 있다는 장점이 존재한다.

 

이 포스팅은 윤성우님의 열혈 C를 기반으로 작성되었습니다.

'C' 카테고리의 다른 글

14. 메모리 및 동적할당  (0) 2021.06.28
11. 구조체와 사용자 정의 자료형  (0) 2021.06.27
10. 문자열 관련 함수  (0) 2021.06.27
9. 함수 포인터 & void 포인터  (0) 2021.06.26
8. 2차원 배열과 포인터  (0) 2021.06.26

+ Recent posts