WinCNT

C 언어 - 16. 구조체 본문

Study/C

C 언어 - 16. 구조체

WinCNT_SSS 2021. 10. 2. 02:32

구조체(Structure Type)란?


구조체란?
하나 이상의 변수묶어새로운 자료형(객체)을 정의하는 도구
by 나무위키

구조체를 이용하면 기본 타입(int, char) 외에도 다양한 자료형(객체)를 표현할 수 있다

 

 

 

구조체와 배열, 클래스의 차이점


구조체와 배열의 차이점
  • 구조체 : 여러 자료형의 집합
  • 배열 : 같은 자료형의 집합

 

C언어의 구조체와 다른 언어의 구조체, 클래스의 차이점

C언어에는 구조체만 있지만, C++와 같이 구조체와 클래스를 동시에 제공하는 언어도 존재한다

하지만 C와 C++이 제공하는 구조체와 클래스에는당연하게도차이점이 존재한다

  • 구조체(C) : 내부에 자료형만 사용 가능, 접근 지정자나 함수는 사용 불가
  • 구조체(C++) : 내부에 자료형 외에도 함수나 접근 지정자도 사용 가능
  • 클래스(C++) : C++에서 구조체와 클래스는 거의 동일한 구조를 가짐
    ※ 단, 클래스는 디폴트 접근 설정이 private이지만 구조체는 public이다
       (C의 구조체와 호환하기 위해 C++의 구조체는 클래스와 디폴트 접근 지정자가 다름)

 

여담으로 C#에서도 구조체와 클래스의 역할은 비슷하지만 다음과 같은 차이점도 존재한다

  • C#에서의 구조체 : 값(Value)타입, 스택 메모리에 생성
    ※ 스택 메모리에 바로 할당되기 때문에 클래스보다 처리 속도가 빠르다
  • C#에서의 클래스 : 참조(Reference)타입, 힙 메모리에 생성
    ※ 힙 메모리에 할당되기 때문에 구조체보다 메모리 절약에 유리하다

 

 

 

구조체의 선언


struct 구조체명
{
    자료형1 변수명1;
    자료형1 변수명1;
    ...
};

예시) 구조체 선언의 예시

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



 

 

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


  1. 구조체의 변수에 접근할 때에는 온점(.)을 사용한다
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    
    struct Student
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    };
    
    int main(void)
    {
        //구조체 변수 선언
        struct Student s;
        //구조체 변수에 접근
        strcpy(s.studentId, "201501329"); //이미 할당된 배열에 문자열을 바로 넣을 수 없으므로 strcpy사용
        strcpy(s.name, "홍길동");
        s.grade = 4;
        strcpy(s.major, "경영학과");
    
        //출력
        printf("학번 : %s\n", s.studentId);
        printf("이름 : %s\n", s.name);
        printf("학년 : %d\n", s.grade);
        printf("학과 : %s\n", s.major);
    
        return 0;
    }
  2. 하나의 구조체 변수만 사용하는 경우 정의와 동시에 변수 선언도 가능하다
    이 경우의 변수는 전역 변수로 사용된다
    struct Student
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    } s;​
    
    //혹은 선언과 동시에 초기화를 할 경우
    struct Student
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    } s = { "201501329", "홍길동", 4, "경영학과" };
  3. 구조체의 변수 선언 시, 중괄호를 이용하여 한 번에 초기화 할 수도 있다
    struct Student
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    };
    
    int main(void)
    {
        //구조체 변수 선언 및 초기화
        struct Student s = { "201501329", "홍길동", 4, "경영학과" };
        
        //출력
        printf("학번 : %s\n", s.studentId);
        printf("이름 : %s\n", s.name);
        printf("학년 : %d\n", s.grade);
        printf("학과 : %s\n", s.major);
    
        return 0;
    }​
  4. typedef 키워드를 사용하여 구조체를 임의의 자료형으로 만들면, 변수 선언 시 struct 키워드를 생략할 수 있다
    #include<stdio.h>
    #include<string.h>
    
    //typedef를 이용한 구조체 정의
    typedef struct Student
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    } Student;
    
    int main(void)
    {
        //typedef를 이용한 구조체의 변수 선언
        Student s = { "201501329", "홍길동", 4, "경영학과" }; //struct 생략 가능
    
        //출력
        printf("학번 : %s\n", s.studentId);
        printf("이름 : %s\n", s.name);
        printf("학년 : %d\n", s.grade);
        printf("학과 : %s\n", s.major);
    
        return 0;
    }​
  5. typedef 키워드를 사용하는 경우, 익명 구조체의 등장으로 인해 구조체명이 없어도 컴파일러가 인식해준다
    typedef struct //Student(구조체명) 생략 가능
    {
        char studentId[10];
        char name[100];
        int grade;
        char major[100];
    } Student;
    
    int main(void)
    {
        //typedef를 이용한 구조체의 변수 선언
        Student s = { "201501329", "홍길동", 4, "경영학과" };
    
        //출력
        printf("학번 : %s\n", s.studentId);
        printf("이름 : %s\n", s.name);
        printf("학년 : %d\n", s.grade);
        printf("학과 : %s\n", s.major);
    
        return 0;
    }​

 

 

 

구조체가 포인터 변수로 사용되는 경우


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

 

#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

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

int main(void)
{
    //구조체 포인터 변수 선언
    Student* s = (Student*)malloc(sizeof(Student));

    if (s != NULL) //malloc함수가 성공했을 시
    {
        //구조체 포인터 변수에 접근
        strcpy(s->studentId, "20151329");
        strcpy(s->name, "홍길동");
        s->grade = 4;
        strcpy(s->major, "경영학과");

        //출력
        printf("학번 : %s\n", s->studentId);
        printf("이름 : %s\n", s->name);
        printf("학년 : %d\n", s->grade);
        printf("학과 : %s\n", s->major);
    }
    return 0;
}