C

열혈강의 자료구조 - 연습문제 2장 01번

돌맹이시터 2021. 1. 20. 18:01

 

프리렉 열혈강의 자료구조 연습문제 2장 1번문제 소스를 작성해보았습니다.

연습문제 해답이 따로 없는 부분이기 때문에

저자님께서 생각한 소스가 맞는지는 모르겠지만 결과물은 정상적으로 출력되는 것을 확인할 수 있었습니다.

 

 

우선 문제는 다음과 같습니다.

 

다음과 같이 구조체를 이용하여 학생 기록부 자료를 저장하려고 합니다.

아래 구조체와 배열을 이용하여 5명의 국어, 영어, 수학 점수 및 평균을 구하는 프로그램을 작성해보세요.

 

위의 문제와 함께 학생 5명의 정보가 주어졌는데

각각 이름, 국어점수, 영어점수, 수학점수는 다음과 같습니다.

lee, 81, 79, 99

kim, 80, 82, 78

park, 79, 85, 75

hong, 75, 87, 82

jung, 90, 89, 65

 

 

 

 

먼저 라이브러리와 구조체를 작성해줍니다.

그리고 학생들의 이름 및 점수 정보를 입력받을 함수를 작성했어요

출력함수도 작성했습니다.

메인함수 앞에 함수를 모두 작성해버리면 소스가 지저분해지기 때문에

메인함수 내에서 사용할 수 있도록 선언은 미리 해두고, 메인함수 뒷부분에 소스를 작성해두었습니다.

 

 

 

 

메인함수입니다.

먼저 동적 메모리를 할당해주고,

메모리 할당에 있어서 오류가 있는지 확인하면서 소스를 작성했습니다.

열혈강의 자료구조 교재에 나오는 NULL 검사를 활용해보았는데

메모리 할당이 불가능할 경우에 할당된 메모리 블록의 주소값으로 NULL을 반환하는데,

이러한 경우 NULL로 반환된 주소로 다른 연산을 수행하면 프로그램이 죽기 때문에 malloc 함수 사용한 이후 NULL이 아닌지 검사를 하라고 합니다.

free함수 또한 사용해주었는데,

프로그램에서 메모리 사용이 끝난 다음 free를 이용해 메모리를 해제하라고 합니다.

 

요즘은 램을 큰 용량으로 쓰기도 하고 예전에 쓰여진 책이기도 해서,

이 부분을 궁금해서 찾아보았는데,

스택오버플로우에서 해당 내용에 대해 궁금해하는 사람들이 많았고

답변을 단 대부분의 현직 종사자들 역시 malloc을 사용할 경우 반드시 free를 통해 해제하는 것이 좋다고 하네요

 

물론 여러가지 상황이 있고, 어떤 경우는 해제하지 않아도 되는 경우가 있기는 하지만

그런 상황들을 구분할 수 있는 경지에 이르기까지는 시간이 오래 걸릴거고

초보일 때부터 습관을 들여두는 것이 좋을 듯 합니다.

 

 

 

memset 함수를 사용해서 동적 메모리 할당을 받은 부분을 0으로 초기화했습니다.

malloc에 의해 할당된 메모리 영역은 대부분 쓰레기 값들로 채워져 있기 때문에

프로그램의 안정성을 고려해서 0으로 초기화시켜주는 것이 좋다고 하네요

말을 잘 들어야죠..

 

그런 다음 input함수를 이용해 학생들의 정보를 입력해주고, 원하는 값을 출력 후, 메모리 해제까지 완료했습니다.

 

 

 

 

학생 점수 입력함수와 결과 출력함수를 각각 작성했습니다.

각각의 학생의 점수 평균값 구하는 것도 그냥 입력함수에 넣어버렸어요

문제에서 점수 부분을 모두 float함수로 줬는데

소수값까지 길게 출력되는게 싫어서 .f, .2f 들을 사용했습니다.

 

 

 

 

원하던대로 깔끔하게(?) 결과가 출력되서 기분이 좋네요

 

 

 

------------

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

typedef struct Student

{

    char name[30];

    float kor;

    float eng;

    float math;

    float avg;

} Student;

 

void input_data(Student *student, char *name, float kor, float eng, float math); //학생 점수 입력함수

void output(Student *student); //결과 출력함수

 

int main(void)

{

    Student *ptr_student_new = (struct Student*)malloc(sizeof(Student)*5); //동적 메모리 할당

    if (ptr_student_new != NULL) // NULL 검사 수행, 메모리 할당이 불가능한 경우에 메모리 시작 주소에 NULL을 반환한다. NULL로 반환된 주소로 연산 수행할 경우 프로그램이 죽어버릴 수 있기 때문에 malloc 함수 사용 시, NULL이 아닌지 검사해보는 게 필요하다고 한다.

    {

        memset(ptr_student_new, 0, sizeof(Student)*5); //할당된 메모리 영역을 0으로 초기화

        input_data(ptr_student_new, "lee", 81, 79, 99); //학생들의 점수 데이터 입력

        input_data(ptr_student_new, "kim", 80, 82, 78);

        input_data(ptr_student_new, "park", 79, 85, 75);

        input_data(ptr_student_new, "hong", 75, 87, 82);

        input_data(ptr_student_new, "jung", 90, 89, 65);

        output(ptr_student_new);

        free(ptr_student_new); //동적 메모리 할당 해제

    }

    else

        printf("메모리 할당 오류\n");

    return 0;

}

 

void input_data(Student *student, char *name, float kor, float eng, float math) //학생 점수 입력함수

{

    int i;

    strcpy(student[i].name, name);

    student[i].kor = kor;

    student[i].eng = eng;

    student[i].math = math;

    student[i].avg = (student[i].kor+student[i].eng+student[i].math)/3;

    i++;

}

 

void output(Student *student) //결과 출력함수

{

    for (int j=0; j<5; j++)

    {

        printf("---student %d---\n",j+1);

        printf("name : %s\nkor : %.f\neng : %.f\nmath : %.f\naverage : %.2f\n", student[j].name, student[j].kor, student[j].eng, student[j].math, student[j].avg);

    }

}