--> [C/C++] 구조체와 사용자 정의 자료형 01

[C/C++] 구조체와 사용자 정의 자료형 01

구조체의 정의


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

 

프로그램 내에서 만약 학생에 대한 정보 (이름, 나이, 성별)를 가지기 위해서는 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;
}
 

 

 

 

 

댓글(0)

Designed by JB FACTORY