컴퓨터 공부/© C

[C언어] 14. 구조체

letzgorats 2021. 2. 14. 04:50

14. 구조체

 

 

<구조체>

- 여러 개의 변수를 묶어 하나의 객체를 표현하고자 할 때 구조체를 사용 할 수 있다.

- 캐틱터, 몬스터, 학생, 좌표 등 다양한 객체 모두 프로그래밍 언어를 이용해 표현 할 수 있다.

 

<구조체의 정의와 선언>

            struct 구조체명{

                 자료형1 변수명 1;

                          자료형2 변수명 2;

                 ……        

}

 

(예제1)한 명의 학생에 대한 정보를 담고 있는 구조체를 만들어보자.

#include <stdio.h>

struct Student {

        char studentId[10];

        char name[10];

        int grade;

        char major[100];

};

(해설) 학생에 대한 정보를 담고 있는 구조체를 만들어 본것이다. 학생의 학번, 이름, 학년, 전공 등을 자료형이 무엇인지 판단해서 잘 담을 수 가 있다.

 

 

<구조체 변수의 선언과 접근>

- 기본적으로 구조체의 변수에 접근할 때 온점(.)을 사용한다.

 

(예제2) 구조체의 변수에 접근하는 법-온점(.)사용

#include <stdio.h>

struct Student{

        char studentId[10];

        char name[10];

        int grade;

        char major[100];

};

int main(void) {

        struct Student s;

        strcpy(s.studentId, "20171601");

        strcpy(s.name, "김정엽");

        s.grade = 2;

        strcpy(s.major,"소프트웨어학과");

        system("pause");
        return 0;
}

(해설) main함수 안에서 struct 구조체명 구조체 변수 ; 를 정하고 strcpy를 불러와 안에 구조체 변수에 .(온점)을 사용해서 접근한다.

 

(예제3) 학생 구조체 만들어서 활용

#include <stdio.h>


struct Student{
        char studentId[10];
        char name[10];
        int grade;
        char major[100];
};

int main(void) {

        struct Student s;
        strcpy(s.studentId, "20171601");
        strcpy(s.name, "김정엽");
        s.grade = 2;
        strcpy(s.major,"소프트웨어학과");
        printf("학번:%s\n",s.studentId);
        printf("이름:%s\n", s.name);
        printf("학년:%d\n", s.grade);
        printf("학과:%s\n", s.major);
        
        system("pause");
        return 0;
}

(해설) 이런 식으로 출력을 하면 원하는 값을 출력할 수 있다. 이렇게 성공적으로 하나의 구조체를 선언하고 접근해서 구조체에 담긴 값들을 출력하는 것까지 해보았다.

 

 

<구조체의 정의와 선언>

- 하나의 구조체 변수만 사용하는 경우 정의와 동시에 선언을 할 수 있다.

- 이 경우 변수는 전역 변수로 사용된다.

 

(예제4) 정의와 선언을 동시에

struct Student{

        char studentId[10];

        char name[10];

        int grade;

        char major[100];

} s;

(해설) 구조체를 정의하는 중괄호 바로 밖에 구조체 변수를 써주고 ;(세미콜론)으로 닫아주면 그게 정의와 선언을 동시에 한 것이다. 이 때 변수 s는 전역변수이며 바로 main함수에 접근할 수 있게 된다. main함수 안에서 따로 구조체 변수를 선언하지 않고 이러한 방식으로  바로 선언을 할 수 있다는 것이다. , 이러한 방식은 오직 하나의 변수만 사용이 될 때 가능하다. 솔직히 많이 사용되지는 않지만 그냥 이런게 있구나 정도로만 알고 있어라.

 

 

<구조체의 초기화>

- 구조체의 변수를 한번에 초기화하기 위해서는 중괄호에 차례대로 변수의 값을 넣는다.

 

(예제5) 구조체 변수를 한번에 초기화

#include <stdio.h>

struct Student {

        char studentId[10];
        char name[10];
        int grade;
        char major[100];

};

int main(void) {

        struct Student s = {"20171601","김정엽",2,"소프트웨어학과"};

        printf("학번:%s\n", s.studentId);

        printf("이름:%s\n", s.name);

        printf("학년:%d\n", s.grade);

        printf("학과:%s\n", s.major);

        system("pause");
        return 0;
}

(해설) main함수 안에서 struct Student s;에 중괄호를 넣어서 그 안에 차례대로 변수의 값을 넣으면 한번에 초기화를 시킬 수 있다. struct Student s={변수의 값들 차례로 쭈욱}; 여기서 주의할 점은 핫번,이름,학년,학과 순이니까 차례대로 이 순서대로 값을 넣어줘야 한다는 것이다.

 

따라서 이런 형태로 초기화하는 것도 가능하다.

(예제6)

#include <stdio.h>

struct Student {

        char studentId[10];

        char name[10];

        int grade;

        char major[100];

} s = { "20171601","김정엽",2,"소프트웨어학과" };

int main(void) {

        printf("학번:%s\n", s.studentId);

        printf("이름:%s\n", s.name);

        printf("학년:%d\n", s.grade);

        printf("학과:%s\n", s.major);

        system("pause");
        return 0;
}

(해설) 결론적으로는 구조체를 만들고(정의하고) 구조체 변수를 선언함과 동시에 그 안에 있는 값들을 한번에 넣어주는 것(초기화)까지 가능하다는 것이다. 이렇게 쓸 수 있다는 것만 알고 있어도 된다. 사실 이런 식으로 쓰는 건 거의 찾아보기 힘들거다. 개념은 잡고 가자.

 

<더 짧게 구조체 정의하기>

- typedef 키워드를 이용하면 임의의 자료형을 만들 수 있으므로 선언이 더 짧아진다.

 

(예제7)

#include <stdio.h>

typedef struct Student {

        char studentId[10];
        char name[10];
        int grade;
        char major[100];

}Student;

int main(void) {

        Student s = { "20171601","김정엽",2,"소프트웨어학과" };

        printf("학번:%s\n", s.studentId);

        printf("이름:%s\n", s.name);

        printf("학년:%d\n", s.grade);

        printf("학과:%s\n", s.major);

        system("pause");
        return 0;
}

(해설) 어떠한 자료형을 임의대로 정의하기 위해서 typedef 가 사용된다. 하나의 변수를 만들어 줄 때 struct Student 처럼 앞에 struct를 붙여야지 구조체 자료형이라는 것을 알 수 있는 건데, 이제 이게 너무 길고 귀찮아서 Student라고만 짧게 쓰고 싶다면 main함수 밖에서 아예 struct를 정의할 때 stuct앞에다가 typedef를 써주면 된다. 그러면, 그 이후로는 struct Student라는 구조체를 나는 그냥 Student 라고 부르겠다 가 가능해지는 것이다. 그래서 main함수에서는 이제 struct를 붙이지 않고 Stduent만 써도 학생 구조체 변수를 만들 수 있게 된다는 것이다.

 

 

- 최근에는 익명 구조체의 개념이 등장하여, 구조체 이름 부분을 비워 놓아도 된다.

 

(예제8)익명 구조체

#include <stdio.h>


typedef struct {

        char studentId[10];
        char name[10];
        int grade;
        char major[100];

}Student;

int main(void) {

        Student s = { "20171601","김정엽",2,"소프트웨어학과" };

        printf("학번:%s\n", s.studentId);

        printf("이름:%s\n", s.name);

        printf("학년:%d\n", s.grade);

        printf("학과:%s\n", s.major);

        system("pause");
        return 0;
}

(해설) 구조체의 이름 자체를 비워 놓아도 컴파일러가 알아서 인식을 한다. 구조체를 정의할 때 typedef struct 라고만 쓰고 그 구조체변수명을 main함수 밖에서 Student;라고만 해주면, 컴파일러가 알아서 이 구조체가 Student라는 것을 인식하게 된다는 것이다.

 

 

<구조체 포인터 변수에 접근하기>

- 구조체가 포인터 변수로 사용되는 경우 내부 변수에 접근할 때 화살표(->)를 사용한다.

 

(예제9) 구조체가 포인터 변수로 사용되는 경우

#include <stdio.h>

typedef struct {

        char studentId[10];
        char name[10];
        int grade;
        char major[51];

}Student;

int main(void) {

        Student* s = malloc(sizeof(Student));

        strcpy(s->studentId,"20171601");

        strcpy(s->name, "김정엽");

        s->grade = 2;

        strcpy(s->major, "소프트웨어학과");

        printf("학번:%s\n", s->studentId);

        printf("이름:%s\n", s->name);

        printf("학년:%d\n", s->grade);

        printf("학과:%s\n", s->major);

        system("pause");
        return 0;
}

(해설) 동적 할당을 이용해서 포인터 형태로 접근을 해야하는 경우에는 내부 변수에 접근할 때

s.studentId 가아닌 s->studentId 처럼 화살표를 사용해야한다.

main함수에서 동적 할당을 이용해 하나의 Student라는 구조체변수를 만들어 주고 여기서 s같은 경우는 포인터이기 때문에 이 변수 s가 가리키고 있는 그 메모리 주소에 하나의 Student구조체가 할당이 되어 있는 것이다. 그렇기 때문에 거기에 접근을 해서 학생의 학번을 바꾸겠다. 라는 의미를 가지기 위해서 화살표라는 직관적인 키워드를 사용한다고 보면 된다. strcpy 잊지말고 .(온점)을 쓰면 오류난다. (포인터)*변수를 사용 할 땐 내부 변수에 접근할 때 (->)화살표를 사용한다!

 

 

(정리)

1. 지금까지는 변수를 만들어서 그 변수를 배열에 넣는 방식으로

   "동일한 속성을 가지는 하나의 변수"를 여러 개 사용하는 식의 처리가 가능했는데,

    이제는 여러 개의 변수 자체가 하나로 모여가지고 일종의 특성을 구성하는 구조체라는 것을 만들 수 있다.

2. 구조체현실 세계의 객체를 소스코드 상에서 매우 쉽게 표현 할 수 있도록 해준다.

 

반응형