혼자 공부하는 C언어 17챕터 도전실전예제
문제
성적 처리 프로그램
학생 5명의 국어, 영어, 수학 점수를 입력하여 총점, 평균, 학점을 구하고 총점 순으로 정렬하여 출력합니다. 학점은 평균이 90점 이상이면 A, 80점 이상이면 B, 70점 이상이면 C, 그 외는 F로 평가합니다.
풀이과정: 정렬을 잘 하느냐가 이번 문제의 핵심이다.
찾아보니 정말 다양한 정렬 방법이 있었다. 이번에 사용한 정렬은 가장 기초적인 선택정렬(selection sort)이다.
선택정렬은 내림차순일 때는 max 파라미터를, 오름차순일 때는 min 파라미터를 사용한다. 이번 문제처럼 내림차순일 때는 가장 앞에 있는 1번째 수를 가장 큰 수로 일단 가정한다. 그 다음 2번째 수와 비교하여 2번째 수가 더 크다면 2를 저장한다. 나머지 수가 모두 2번째 수보다 작다면 저장된 2번째 수를 1번째 수와 교환 한다. 그 다음 큰 수를 찾기 위해서 2번째 수에 저장된 수를 가장 큰 수로 일단 가정한다. 그리고 위의 과정을 계속 반복하면 된다.
#include <stdio.h>
typedef struct
{
int id;
int kor;
int eng;
int math;
int total;
double avg;
char grade;
char name[20];
} Profile;
//구조체 선언
void Input_list(Profile* lp);
void Print_list(Profile* lp);
void Sort_list(Profile* lp);
int main(void)
{
Profile student_list[5];
Input_list(student_list);
printf("# 정렬 전 데이터...\n");
Print_list(student_list);
Sort_list(student_list);
printf("# 정렬 후 데이터...\n");
Print_list(student_list);
return 0;
}
void Input_list(Profile* lp)
//포인터를 받는 함수를 이용하여 call of reference 와 비슷한 효과를 준다.
{
int i;
for (i = 0; i < 5; i++)
{
printf("학번 : ");
scanf("%d", &lp -> id);
printf("이름 : ");
scanf("%s", &lp -> name);
printf("국어, 영어, 수학 점수 : ");
scanf("%d%d%d", &lp -> kor, &lp -> eng, &lp -> math);
lp -> total = lp -> kor + lp -> eng + lp -> math;
lp -> avg = lp -> total / 3.0;
if (lp -> avg >= 90)lp -> grade = 'A';
else if (lp -> avg >= 80)lp -> grade = 'B';
else if (lp -> avg >= 70)lp -> grade = 'C';
else lp -> grade = 'F';
lp++;
// 포인터를 다음 주소로 이동시켜 구조체 배열의 다음 주소에 저장할 수 있도록 한다.
}
}
void Print_list(Profile* lp)
{
int i;
for (i = 0; i < 5; i++)
{
printf("%5d%4s%5d%5d%5d%5d%8.1lf%5c\n", lp[i].id, lp[i].name, lp[i].kor,
lp[i].eng, lp[i].math, lp[i].total, lp[i].avg, lp[i].grade);
//이런식으로, 구조체도 배열과 같은 문법으로도 사용이 가능하다.
}
}
void Sort_list(Profile* lp)
{
Profile temp;
int i, j, max;
for (i = 0; i < 5 - 1; i++)
// 나머지 값이 결정되면 가장 작은 값은 자동으로 결정되기 때문에 배열의 수에서 -1을 해준다.
{
max = i;
for (j = i + 1; j < 5; j++)
// 비교하고자 하는 수의 다음 수부터 시작하여 배열의 마지막 수까지 검색한다.
{
if (lp[max].total < lp[j].total)
{
max = j;
// 만약 j번째에 수가 그 전에 나온 수보다 크다면 max에 저장한다.
}
}
if (max != i)
{
temp = lp[max];
lp[max] = lp[i];
lp[i] = temp;
// 현재 위치를 뜻하는 i에 가장 큰 값이 들어있는 순번을 나타내는 max를 이용해
// i번째 수와 max번째 수를 서로 바꿔준다.
}
}
}