티스토리 뷰

반응형

구조체의 정의


구조체란 하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것을 의미합니다. 그룹 지어진 변수는 서로 다른 자료형의 변수라도 상관없고 포인터 변수나 배열도 그룹에 속할 수 있습니다.

 

프로그램 내에서 만약 학생에 대한 정보 (이름, 나이, 성별)를 가지기 위해서는 3개의 변수가 필요합니다. 이 세 개의 변수는 서로 독립 된 정보를 나타내는 것이 아니라, 하나의 정보를 나타내는 변수들입니다. 즉 학생의 정보' 나타내기 위해 늘 붙어 다녀야 하는 것입니다.

 

1
2
3
4
5
6
struct Student    //Student 구조체를 정의
{
    char *name;        //char* 타입의 구조체 멤버
    int age;        //int 타입의 구조체 멤버
    char *major;    //char* 타입의 구조체 멤버
};

 

첫 번째 줄에서 struct Student라는 선언은 Student라는 이름의 구조체를 정의한다는 의미를 지닙니다. 중괄호 안에는 이 구조체가 가지는 멤버 변수들에 대한 정의가 오게 됩니다. 이런식으로 Student라는 하나의 새로운 자료형이 완성이 되고 이를 가리켜 사용자 정의 자료형이라 부르며 구조체를 이루는 변수들을 구조체 멤버라고 부릅니다.

 

그러면 실제로 이 구조체를 선언하고 멤버에 접근하는 방식을 살펴 보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Student    //Student 구조체를 정의
{
    char *name;// 타입의 구조체 멤버
    int age;        //int 타입의 구조체 멤버
    char *major;    //char* 타입의 구조체 멤버
};
 
 
int main()
{
    Student st1 = { "Lee ki taek",27,"Computer" };    //배열 초기화 문법
    Student st2;
 
    st2.name = "Kim min ho";                        //구조체 멤버 지정하여 초기화
    st2.age = 27;
    st2.major = "Computer";
 
    return 0;
}

 

'Student st1'와 같이 Student를 자료형으로 하는 st1 변수를 선언합니다. 그리고 각 멤버를 초기화 하는 방식으로 첫 번째는 11번 라인과 같이 배열 초기화 문법을 사용하는 방식입니다. 구조체 멤버 변수의 순서에 맞게 순서대로 초기화가 이루어집니다. 두 번째로는 .을 사용하여 각 구조체 멤버변수 이름을 지정하고 원하는 값으로 초기화를 하면 됩니다.

 

구조체 배열과 포인터


구조체 배열을 선언하고 각 요소를 초기화 하는 코드입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct Student    //Student 구조체를 정의
{
    char name[20];

    int age;        //int 타입의 구조체 멤버

    char major[20];    
};
 
 
int main()
{
    Student st[3];
 
    for (int i = 0; i < 3; i++)            //구조체 배열 요소 입력받기
    {
        scanf_s("%s %d %s", st[i].name,20,&st[i].age,st[i].major,20);
    }
    for (int i = 0; i < 3; i++)          //구조체 배열 요소 출력하기       
    {
        printf("%s %d %s \n", st[i].name, st[i].age, st[i].major);
    }
 
    return 0;
}

 

위의 예제는 Student 구조체 배열을 st라는 이름을 선언하고 있습니다. 즉 이제 3명의 학생 정보를 담을 수 있는 배열이 생성 된 것입니다. 인덱스는 0에서 부터 시작하며, 배열의 첫 번쨰 구조체에 접근하기 위해서는 st[0].구조체 멤버 변수 이름 방식으로 접근이 가능합니다.

 

■구조체 변수와 포인터


구조체 변수를 가리킬 수 있는 구조체 포인터를 선언하고 사용하는 방법에 대해서 알아 보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Student    //Student 구조체를 정의
{
    char name[20];
    int age;        //int 타입의 구조체 멤버
    char major[20];    
};
 
 
int main()
{
    Student st1 = { "lee ki raek",27,"Computer" };
    Student* p_st1;        //구조체 포인터 선언
    p_st1 = &st1;        //st1 구조체 주소 값 대입
 
    printf("%s %d %s\n", st1.name, st1.age, st1.major);            //구조체 변수를 이용한 출력
    printf("%s %d %s\n", (*p_st1).name, (*p_st1).age, (*p_st1).major);    //구조체 포인터를 이용한 출력
    printf("%s %d %s\n", p_st1->name, p_st1->age, p_st1->major);        //구조체 포인터를 이용한 출력2
    return 0;
}

 

12번 라인에서 구조체 포인터를 선언하고 13번 라인에서 st1 구조체 변수의 주소 값을 할당하고 있습니다. 15번 라인은 일반 구조체 변수를 이용한 구조체 멤버 변수의 값을 출력하는 방식이며 16번 라인은 *연산자를 활용하여 출력을 하고 있습니다. 마지막 17번 라인에서 ->연산자(간접 멤버 접근 연산)를 통해서 출력 하는 방식을 보여줍니다. (*p_st1).age == p_st1->age는 완전히 같은 의미입니다.

 

또한 16번 라인에서 괄호가 들어가는 것은 *연산자가 .연산자보다 우선순위가 낮기 때문입니다.

따라서 괄호를 해주지 않으면 *p_st1.name == *(p_st1.name)과 같은 의미가 되어 전혀 다른 결과를 내놓게 됩니다.

 

구조체 멤버와 포인터 변수


이번에는 구조체의 멤버로 포인터 변수가 선언되는 것에 관하여 알아 보겠습니다.

 

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
struct Info
{
    char addr[20];
    char tel[20];
};
 
 
struct Student    //Student 구조체를 정의
{
    char name[20];
    int age;        
    char major[20];    
    struct Info* info;    //Info 구조체를 가르킬 수 있는 포인터를 멤버로 선언
};
 
 
int main()
{
    Student st1 = { "lee ki raek",27,"Computer" };
    Info info = {"Busan","010"};
    st1.info = &info;        //st1의 멤버변수 info가 Info 구조체를 가르키도록 함
 
    printf("%s %d %s\n", st1.name, st1.age, st1.major);            
    printf("%s %s\n", st1.info->addr,st1.info->tel);
    
}

 

Student 구조체는 Info 구조체를 가르 킬 수 있는 포인터를 멤버로 가지는 info 포인터를 가지고 있습니다.

그리고 21번 라인에서 st1.info = &info를 통해 info 멤버가 Info 구조체를 가르키도록 하고 있습니다. 24번 라인에서는 -> 연산자를 통해 실제로 Student 구조체의 멤버를 통해 Info 멤버에 접근하여 출력 하고 있습니다.

 

뿐만 아니라 다음과 같이 Student 구조체 멤버 변수로 Student를 가르킬 수 있는 포인터를 멤버로 선언도 가능합니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
struct Student    //Student 구조체를 정의
{
    char name[20];
    int age;        //int 타입의 구조체 멤버
    char major[20];    
    struct Student* next;    //Info 구조체를 가르킬 수 있는 포인터를 멤버로 선언
};
 
 
int main()
{
    Student st1 = { "lee ki raek",27,"Computer" };
    Student st2 = { "Kim Min Ho",27,"Computer" };
    st1.next = &st2;
}
 

 

 

 

 

반응형