CS/C

[2021W C프로그래밍과 실습][예제] 구조체 배열 포인터를 매개변수로 하는 함수 - Bubble sort 함수 활용

아이스얼그레이 2022. 2. 9. 22:19

중간고사 준비도 하고 귀찮아져서 함수부터 포스팅을 띵가먹었다. 블로그 이름과 달리 기록보다 기억을 하기로 했다. 귀찮아서 그런거 아님!

구조체, 배열, 포인터, 함수를 모두 활용하는 예제를 풀었는데 코드분석하고 넘어가면 좋을듯해서 포스팅한다. 문제는 다음과 같다.

- 구조체 배열을 사용하여 어떤 사람의 이름, 국어, 영어, 수학의 성적 점수를 입력 받아서 3과목의 합계, 평균을 구한 후 평균 점수가 높은 것에서 낮은 순으로 정렬하여 성적표를 나타내는 프로그램을 작성(최대 10명 처리)

원래는 함수를 사용하지 않고 main() 함수안에서 다 해결하는 문제였는데, 구조체 함수 파트에서 변형해서 문제가 나왔다.

힌트로 전처리부 코드, main() 함수 코드가 주어졌다.

#include <stdio.h>
#include <stdlib.h>
#define MAX 10 // 최대 처리수를 매크로상수로 정의
#define MSG "===================================" // 출력 형식을 위한 매크로상수

typedef struct {
	char name[MAX];
	int kor, mat, eng, tot;
	double avg;
} score; // 구조체를 score라는 구조체 타입으로 정의

int insert(score* sc, int n); // 점수을 입력하는 함수
void sort(score* sc, int n); /* 평균 점수에 따라 내림차순으로 정렬하는 함수. 아직 bubble sorting
만 배워서 bubble sorting을 활용했다.*/
void print(score* sc, int n); // 정렬 후 형식에 맞게 출력

void main()
{
	score std[MAX];
	int cnt = 0;
	cnt = insert2(std, cnt);
	sort(std, cnt);
	print(std, cnt);
}

 

1. insert 함수

int insert1(score* sc, int n)
{
	int i;
	char y_n;

	for (i = 0; i < MAX; i++)
	{
		printf("데이터를 계속 입력하시겠습니까?(y/n)");
		y_n = getchar();
		while (getchar() != '\n'); // 입력버퍼 초기화

		if (toupper(y_n) == 'N') 
			break;
       // 'n'을 입력하면 반복문을 탈출하고 입력받은 구조체 배열의 개수인 n을 return

		scanf("%s %d %d %d", sc[i].name, &sc[i].kor, &sc[i].eng, &sc[i].mat);
		while (getchar() != '\n'); // 입력버퍼 초기화

		sc[i].tot = sc[i].kor + sc[i].eng + sc[i].mat;
		sc[i].avg = sc[i].tot / 3.0; // avg는 double형 변수이므로 3.0으로 나눠서 type casting

		n++;
	}

	return n;
}

구조체 배열을 함수의 인수로 전달했는데, 이 부분이 참 헷갈렸다. 처음에 코드를 짤때 sc가 구조체 포인터로 선언되어서 scanf에서 sc->name, &sc->kor, &sc->eng, &sc->mat로 입력받고 sc++을 반복해줬다.

뭐 이렇게 써도 동작은 하지만 코드의 가독성이 좀 떨어지는 것 같다.

함수의 매개변수를 구조체의 주소로 받았고, 함수에서 sc[i]로 값을 입력하면 그 주소에 값이 입력된다. 주소를 참조해서 값을 입력했으니 main() 함수의 score std[MAX]에서 변화가 생기는 것이다. 이것 말고는 간단한 코드이다.

n은 몇 명의 정보를 입력받았는지 counting하는 변수이다. main() 함수의 cnt에 저장된다.

 

2. sort 함수

 
void sort(score* sc, int n)
{
	score tmp; // 구조체 정렬을 위해 선언한 임시 구조체

	int i, j;

	for (i = 0; i < n - 1; i++)
		for (j = 0; j < n - i - 1; j++)
			if (sc[j].avg < sc[j + 1].avg) // for문은 bubble sorting 알고리즘
			{
				tmp = sc[j];
				sc[j] = sc[j + 1];
				sc[j + 1] = tmp;
			}
}

sort 함수 또한 구조체 주소를 매개변수로 전달받는다. 그러면 함수내에서 구조체 배열의 순서를 변경해도 주소를 참조해서 변경한것이므로 main() 함수에서도 score std[MAX]가 sort된다. 정렬 코드는 설명 생략. 1, 2번 모두 주소를 매개변수로 전달받았다는 점을 주목해야한다.

 

3. print 함수

void print(score* sc, int n)
{
	int i;

	printf(" 이름  국어 영어 수학 총점 평균\n");
	printf("%s\n", MSG);

	for (i = 0; i < n; i++)
	{
		printf("%s  %3d  %3d  %3d  %3d %5.2lf\n", 
               sc[i].name, sc[i].kor, sc[i].eng, sc[i].mat, sc[i].tot, sc[i].avg);
	}
}

 입력, 정렬이 끝나고 구조체 요소들을 출력하는 함수이다. 이 함수 또한 구조체의 주소를 매개변수로 전달받는다.

코드는 형식만 맞춘거고 출력은 간단하다. 입력받은 구조체 주소 sc 에서 0번 요소부터 n - 1번 요소까지 형식에 맞게 출력하는 코드이다.

출력결과는 다음과 같다.

평균 점수에 따라서 내림차순으로 정렬되었다. 지금 배가 너무 고파서 백오파 씨의 성적을 입력해봤다.