본문 바로가기
C

구조체 struct

by stdlib.h 2016. 5. 5.

구조체는 C의 데이터 타입중 가장 덩치가 크다.

정수나 실수, 또는 문자열 등의 단순한 형태로 나타낼 수 없는 복잡한 데이터를

표현할 때, 구조체가 사용된다.

구조체를 정의내리면 타입이 다른 변수들의 집합이라고 할 수 있다.

배열은 같은 타입의 변수를 여러개 가지지만, 구조체는 다른타입의 변수를 하나의 이름으로 묶은것이다.

ex)

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

사람을 표현하기 위한 구조체


Name 캐릭터형이고, Age는 정수형이고 나머지도 정수형인데, 이외에 자세한 주소

를 기억하고 싶으면 여러 정보가 더 필요할 것이다. 보다시피 각 변수들의 타입

이 서로 달라서 배열로는 묶을 수 없는데, 관련성 있는것들을 하나로 묶어서 선

언할때 구조체를 사용한다.

단 구조체 선언은 어디까지나, 구조체의 모양을 컴파일러에게 알려주는 것일 뿐, 초기

값을 줄 수는 없다. 



구조체변수는 태그를 먼저 정의하고 이 태그로 구조체 변수를 선언하는 것이 일반적

이다. 형식은 다음과 같다. struct 태그명 { 멤버목록 };


키워드 struct 다음에 태그의 이름을 주고 멤버를 나열한다.

태그도 일종의 명칭이므로 규칙에만 맞다면 자유롭게 이름을 붙일 수 있다.


타입이 정의되면 이 타입으로 같은형의 변수를 선언할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};
 
int main(void)
{
    human a, b;
}
 
cs

또한 다음과 같은 선언도 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};
 
int main(void)
{
    human *a, b[100];
}
 
cs

구조체를 인수나 리턴값으로도 사용할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};

human(human a); 

int main(void)
{
    human a, b;
}
 
cs

구조체의 멤버에 참조할때는 -> 또는 . 를 사용하는데, 구조체형 포인터일때 ->를 사

용한다.

포인터나 배열은 첫 번째, 몇번째, 이럴수 있으나 구조체는 각각 크기가 다르므로, 별도의 연산자와 멤버의 이름을 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <string.h>
 
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};
 
int main(void)
{
    human a;
    strcpy(a.name, "유한길");
    a.age = 17;
    a.height = 180;
    a.weight = 54;
    printf("%s %d %d %d\n", a.name, a.age, a.height, a.weight);
}
 
 
 
cs

이런식으로 태그.멤버 를하면 접근 할 수 있다.


예전에 T라는 타입이 있을때, T형 배열과 포인터를 선언할 수 있다고 했다.


그렇다면 구조체도 배열과 포인터를 선언할 수 있다.

고로 다음과 같은 코드도 가능하다.


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
#include <stdio.h>
#include <string.h>
 
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};
 
int main(void)
{
    human *a;
    human b[10];
    int i = 0;
    a = b;
    strcpy((*a).name, "유한길");
    (*a).age = 17;
    (*a).height = 180;
    (*a).weight = 54;
    printf("%s %d %d %d\n", (*a).name, (*a).age, (*a).height, (*a).weight);
}
 
 
 
 
 
cs

 이런식으로 접근하기 어렵지 않은가?


그래서 아까말했던 다른연산자인 -> 를 사용할 수있다.

p가 구조체를 가리키는 포인터이고, m이 멤버일 때

(*p).m 은 p->m 과  같다.


구조체끼리 대입할 수도 있으며, 구조체의 멤버를 초기화 할때는 다음처럼 쓸 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
 
struct human
{
    char name[10];
    int age;
    int height;
    int weight;
};
 
int main(void)
{
    human a;
    a = { "유한길"1718054 };
    printf("%s %d %d %d\n", a.name, a.age, a.height, a.weight);
}
 
 
 
 
 
 
 
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
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
65
66
67
68
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
typedef struct NODE
{
    char name[10];
    int grade;
    int score;
}node;
 
node *find(node *arr, size_t size);
 
int main(void)
{
    node *arr;
    int i;
    int amount;
    node *max;
    puts("학생은 몇명인가요?");
    scanf("%d%*c", &amount);
    if (!(arr = (node*)calloc(1sizeof(node)*amount)))
    {
        puts("error!");
        return 0;
    }
    else
    {
        for (i = 0; i < amount; i++)
        {
            puts("학생의 이름을 입력하여 주십시오.");
            scanf("%s", (arr + i)->name);
            puts("학생의 학년을 입력하여 주십시오.");
            scanf("%d%*c", &((arr + i)->grade));
            puts("학생의 점수를 입력하여 주십시오.");
            scanf("%d%*c", &((arr + i)->score));
        }
        max = find(arr, amount);
        printf("성적이 가장 높은 학생은 %d 학년 %s입니다!\n", max->grade, max->name);
    }
    return 0;
}
 
node *find(node *arr, size_t size)
{
    int max=0;
    int i = 0;
    for (i = 0; i < size; i++)
    {
        if ((arr + i)->score > max)
        {
            max = (arr+i)->score;
        }
    }
    for (i = 0; i < size; i++)
    {
        if ((arr + i)->score == max)
        {
            return (arr + i);
        }
    }
}
 
 
 
 
 
 
cs

사용자에게 학생들수만큼 입력받아서 가장 성적이 높은 학생의 학년과 이름을 출력한다.