Language/C

[C] 구조체(Structure)

nowkoes 2024. 1. 31. 18:11

구조체

개요

출처: cppreference.com

 

 프로그래밍을 하다 보면 서로 다른 타입의 변수들을 하나의 단위로 묶어야 할 때가 있다. 예를 들어, 학생들의 점수를 관리하는 프로그램을 만든다고 가정해 보자. 학생들의 이름을 저장해야 하므로 문자형 배열, 점수가 필요하므로 정수, 혹은 실수형 데이터가 필요할 것이다. 즉, 학생 한 명당 여러 개의 변수가 필요하므로, 학생 수가 많아질수록 관리해야 할 변수의 수가 기하급수적으로 늘어난다. 이는 가독성의 저하와 코드의 복잡성 증대로 인해 오류 발생 가능성을 야기한다.

 

 이런 문제점을 해결하기 위한 방법으로 구조체를 사용하는 것이 매우 효과적이다. 구조체(Struct)서로 다른 타입의 변수들을 하나의 논리적 단위로 묶는 사용자 정의 타입이다. 위의 예시에서 구조체를 이용하여 각 학생들의 정보를 '학생'이라는 하나의 단위로 묶으면, 코드가 단순해지고 학생 한 명의 정보를 하나의 구조체 인스턴스로 취급할 수 있어 각각의 학생들을 쉽게 관리할 수 있다.

 

 이번 시간에는 이러한 구조체에 대해 알아보는 시간을 가져보겠다.


본문

사용법

 먼저 구조체의 기본적인 구성부터 알아보자. 구조체는 개요 부분에서 언급한 것처럼, 다양한 자료형과 변수들로 이루어져 있다. 이를 struct 키워드를 이용하여 정의한다. 위의 예시처럼 학생들에 대한 정보를 담고 있는 새로운 자료형 Students를 정의하면 다음과 같다.

 

struct Students
{
	char _name[100];
	float* _scores;
};

 

 정의한 구조체를 사용하기 위해 메인 함수에서 다음과 같이 Students를 자료형으로 갖는 변수 st를 초기화해 준다.

 

int main()
{
    struct Students st;
    int num;

 

 여기서 num은 학생이 치른 시험의 개수를 의미한다. 이때 구조체를 사용할 땐 반드시 앞에 struct 키워드를 붙여줘야 한다. 이는 C언어에서는 구조체를 선언하고 그 타입을 식별하기 위함이다. C언어는 기본적으로 구조체 이름을 그 자체로 타입명으로 사용하지 않는다. 즉, C언어의 타입 시스템이 기본 데이터 타입과 사용자 정의 타입을 명확하게 구분하도록 설계되었기 때문에 struct 키워드를 사용해야 한다. 만약 해당 과정을 생략하고 싶으면 typedef이라는 키워드를 이용해 struct를 정의해줘야 한다. 

 

    printf("Enter student's name: ");
    scanf_s("%99s", st._name, (unsigned)sizeof(st._name));

    printf("Enter the number of scores: ");
    scanf_s("%d", &num);

 

 이제 학생의 이름과 점수의 개수를 scanf_s로 입력받는다.

 

    initStudents(&st, num);
    
    ...
    
void initStudents(struct Students* s, int num)
{
	s->_scores = (float*)malloc(num * sizeof(float));
}

 

 그리고 구조체에 선언된 포인터 변수를 동적 할당으로 초기화하기 위해 malloc 함수를 사용해야 한다. 이때 구조체 내에서는 함수를 사용할 수 없다. 이는 C언어의 설계 원리와 타입 시스템에서 기인한다. 즉, C언어는 절차 지향 언어로, 데이터와 함수를 분리하여 처리하는 것을 기본 원칙으로 하기 때문이다.

 

    printf("Enter n scores for %s:\n", st._name);
    for (int i = 0; i < 5; i++) 
    {
        printf("Score %d: ", i + 1);
        scanf_s("%f", &st._scores[i]);
    }

    printf("\nStudent Name: %s\n", st._name);
    printf("Scores: ");
    for (int i = 0; i < 5; i++) 
        printf("%.2f ", st._scores[i]);
    
    printf("\n");

    exitStudents(&st);

    return 0;
}

	...
    
void exitStudents(struct Students* s)
{
	free(s->_scores);
}

 

 그리고 학생에 대한 정보들을 입력받고, 메모리를 free 함수를 이용해 해제하였다.

 

총합본

더보기
#include <stdio.h>
#include <stdlib.h>

struct Students
{
	char _name[100];
	float* _scores;
};

void initStudents(struct Students* s, int num);
void exitStudents(struct Students* s);


int main()
{
	struct Students st;
    int num;

    printf("Enter student's name: ");
    scanf_s("%99s", st._name, (unsigned)sizeof(st._name));

    printf("Enter the number of scores: ");
    scanf_s("%d", &num);

    initStudents(&st, num);

    printf("Enter n scores for %s:\n", st._name);
    for (int i = 0; i < 5; i++) 
    {
        printf("Score %d: ", i + 1);
        scanf_s("%f", &st._scores[i]);
    }

    printf("\nStudent Name: %s\n", st._name);
    printf("Scores: ");
    for (int i = 0; i < 5; i++) 
        printf("%.2f ", st._scores[i]);
    
    printf("\n");

    exitStudents(&st);

    return 0;
}

void initStudents(struct Students* s, int num)
{
	s->_scores = (float*)malloc(num * sizeof(float));
}

void exitStudents(struct Students* s)
{
	free(s->_scores);
}

요약

구조체
1. 정의: 서로 다른 타입의 변수들을 하나의 논리적 단위로 묶는 사용자 정의 타입
2. 사용법: struct 키워드와 typedef 키워드를 이용하여 구조체를 선언한 후 원하는 곳에서 호출
반응형

'Language > C' 카테고리의 다른 글

[C] 메모리 동적 할당  (0) 2024.01.29
[C] 포인터(Pointer)  (2) 2024.01.22