17 - Struct 2
<학습하기>
열거형 (enum)
데이터 타입 중에는 몇가지 값들만 유효한 경우가 있다.
ex)
요일 : Sun, Mon, Tue, Wed, Thu, Fri, Sat 7개의 값만 가능.
남성/여성 : Male, Female 2개의 값만 가능.
이럴 경우 유효한 값들만 나열해서, 그 값들만 저장할 수 있도록 하는 것이 열거형.
형식
열거형 정의
지금 당장 열거형 변수를 만드는 것이 아니라,
앞으로 이런 열거형을 만들겠다고 미리 정의해 놓음.
enum 열거형이름 {가능한 값, 가능한 값, ...};
ex)
enum WeekDay { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
enum Gender { Male, Female };
열거형 변수 만들기
enum 열거형이름 변수이름;
enum WeekDay today; // today에는 7개의 요일값만 들어갈 수 있음.
enum Gender puppy = Male;
다음과 같은 명령은 불가
today = Female;
Puppy = 1;
삼항연산자
간단한 if명령어를 대신할 수 있는 연산자.
다른 연산자와는 달리 3개의 항을 가지고 있다.
형식
A ? B : C
작동방식
1. 먼저 A식을 계산한다.
2. 만약 A식의 계산 결과가 true라면, B식을 계산해서 반환한다.
3. 만약 A식의 계산 결과가 false라면 C식을 계산해서 반환한다.
ex)
printf("%d는 %s입니다. \n", intVar, intVar % 2 == 0? "짝수" : "홀수");
시험 등수를 계산하는 알고리즘
알고리즘1
내가 1등이라 가정
만약 1번학생 성적이 나보다 높다면,
내등수 하나 떨어짐.
만약 2번 학생 성적이 나보다 높다면
내 등수 하나 떨어짐.
:
:
만약 10번 학생 성적이 나보다 높다면
내등수 하나 떨어짐.
알고리즘 2 : 내 등수 rank
rank = 1
만약 1번학생 성적이 나보다 높다면
++rank
만약 2번학생 성적이 나보다 높다면
++rank
:
:
만약 10번학생 성적이 나보다 높다면
++rank
알고리즘3 : 이렇게 반복하는거 반복문 사용하자.
rank = 1
student를 1부터 끝까지 반복.
만약 student번 학생 성적이 나보다 높다면
++rank
for(student = 0; student < 10; ++student)
그러나 이 방법은 한 학생의 등수만을 구할 수 있다.
<실습하기>
#include <stdio.h>
// 다음 데이터를 가지고 각 학생들의 총점과 평균, 합격 여부를 계산해서 출력하라.
// 그리고 각 학생들의 등수를 구하여라.
enum ExamResult
{
Unident,
Pass,
Fail
};
struct Exam
{
int cLang;
int java;
int python;
enum ExamResult result;
int total;
double avg;
int rank; //시험 등수
};
struct Student
{
char name[30];
struct Exam exam;
};
void CalcExamResult (struct Student *stud);
void FindRank (struct Student *stud, struct Student studInfo[10]);
//이렇게 선언해줘여함.
main()
{
struct Student studentInfo[] =
{
{"홍길동", {88, 73, 89, Unident}},
{"일지매", {87, 82, 73, Unident}},
{"심청", {76, 88, 89, Unident}},
{"이몽룡", {57, 45, 67, Unident}},
{"성춘향", {65, 85, 68, Unident}},
{"장화", {85, 75, 98, Unident}},
{"홍련", {96, 68, 63, Unident}},
{"흥부", {44, 65, 58, Unident}},
{"놀부", {76, 69, 77, Unident}},
{"임꺽정", {89, 78, 83, Unident}}
};
//각 학생들의 총점과 평균을 계산.
int student;
for(student = 0; student <10; ++student)
CalcExamResult(&studentInfo [student]);
//student번째 학생의 평균과 총점을 계산하고 합격여부를 가리는 함수.
//포인터로 바꿧으니까 &studentInfo로 변경.
//각 학생들의 총점과 평균을 출력
for (student = 0; student < 10; ++student)
printf("%s : 총점 %d 평균 %f\n", studentInfo[student]. name,
studentInfo[student]. exam .total,
studentInfo[student]. exam .avg);
//합격자들만 출력
puts("합격자들 리스트");
for(student = 0; student < 10; ++student)
if(studentInfo[student].exam.avg > 60)
printf("%s\n", studentInfo[student].name);
//밑에 삼항연산자로 이미 나눈 P/F 사용하기
puts("합격자들 리스트");
for(student = 0; student < 10; ++student)
if(studentInfo[student].exam.result == Pass)
printf("%s\n", studentInfo[student].name);
//등수를 구하는 함수
/*FindRank(&studentInfo[0], studentInfo); //0번 학생의 등수를 구하는 함수.
//전체 학생의 정보를 알고 있어야 등수를 구할 수 있으므로 studentInfo도 전달해야함.
//구조체 변수 안의 정보 (exam.rank)를 바꿔야 하므로 주소로 바꿔 전달해야한다.
FindRank(&studentInfo[1], studentInfo); //1번 학생의 등수를 구하는 함수.
FindRank(&studentInfo[2], studentInfo); //2번 학생의 등수를 구하는 함수.
*/
for (student = 0; student < 10; ++student)
FindRank(&studentInfo[student], studentInfo);
puts("각 학생 등수 출력");
for(student = 0; student < 10; ++student)
printf("이름 : %s 총점 : %d 등수 : %d\n", studentInfo[student].name,studentInfo[student].exam.total,studentInfo[student].exam.rank);
}
void FindRank (struct Student *stud, struct Student studInfo[10])
{
//내 등수를 1로 간주
int rank =1;
int student;
for(student =0; student < 10; ++student) //모든 학생들의 성적을 비교
if(stud->exam.total /*내성적*/ < studInfo[student].exam.total/*다른학생성적*/)
++rank;
stud->exam.rank =rank; //내 등수 저장.
//나보다 잘하는 학생이 있으면 내 등수가 하나씩 떨어짐.
}
void CalcExamResult (struct Student *stud)
{
//총점과 평균 계산
int total = stud->exam.cLang + stud->exam.java + stud->exam.python;
double avg = total/3.0;
stud->exam.total = total;
stud->exam.avg = avg;
//stud.exam 하면 안돼!
//원래 있던 구조체의 값에 변화가 없기 때문
//그러면 포인터를 쓰자.
//stud.exam 부분을 모두 . 에서->로 변경.
//합격 여부
/*
if (avg>=60)
stud->exam.result = Pass;
else
stud->exam.result = Fail;
*/
//삼항연산자 사용
stud->exam .result = avg >= 60 ? Pass : Fail;
}
열거형 (enum)
데이터 타입 중에는 몇가지 값들만 유효한 경우가 있다.
ex)
요일 : Sun, Mon, Tue, Wed, Thu, Fri, Sat 7개의 값만 가능.
남성/여성 : Male, Female 2개의 값만 가능.
이럴 경우 유효한 값들만 나열해서, 그 값들만 저장할 수 있도록 하는 것이 열거형.
형식
열거형 정의
지금 당장 열거형 변수를 만드는 것이 아니라,
앞으로 이런 열거형을 만들겠다고 미리 정의해 놓음.
enum 열거형이름 {가능한 값, 가능한 값, ...};
ex)
enum WeekDay { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
enum Gender { Male, Female };
열거형 변수 만들기
enum 열거형이름 변수이름;
enum WeekDay today; // today에는 7개의 요일값만 들어갈 수 있음.
enum Gender puppy = Male;
다음과 같은 명령은 불가
today = Female;
Puppy = 1;
삼항연산자
간단한 if명령어를 대신할 수 있는 연산자.
다른 연산자와는 달리 3개의 항을 가지고 있다.
형식
A ? B : C
작동방식
1. 먼저 A식을 계산한다.
2. 만약 A식의 계산 결과가 true라면, B식을 계산해서 반환한다.
3. 만약 A식의 계산 결과가 false라면 C식을 계산해서 반환한다.
ex)
printf("%d는 %s입니다. \n", intVar, intVar % 2 == 0? "짝수" : "홀수");
시험 등수를 계산하는 알고리즘
알고리즘1
내가 1등이라 가정
만약 1번학생 성적이 나보다 높다면,
내등수 하나 떨어짐.
만약 2번 학생 성적이 나보다 높다면
내 등수 하나 떨어짐.
:
:
만약 10번 학생 성적이 나보다 높다면
내등수 하나 떨어짐.
알고리즘 2 : 내 등수 rank
rank = 1
만약 1번학생 성적이 나보다 높다면
++rank
만약 2번학생 성적이 나보다 높다면
++rank
:
:
만약 10번학생 성적이 나보다 높다면
++rank
알고리즘3 : 이렇게 반복하는거 반복문 사용하자.
rank = 1
student를 1부터 끝까지 반복.
만약 student번 학생 성적이 나보다 높다면
++rank
for(student = 0; student < 10; ++student)
그러나 이 방법은 한 학생의 등수만을 구할 수 있다.
<실습하기>
#include <stdio.h>
// 다음 데이터를 가지고 각 학생들의 총점과 평균, 합격 여부를 계산해서 출력하라.
// 그리고 각 학생들의 등수를 구하여라.
enum ExamResult
{
Unident,
Pass,
Fail
};
struct Exam
{
int cLang;
int java;
int python;
enum ExamResult result;
int total;
double avg;
int rank; //시험 등수
};
struct Student
{
char name[30];
struct Exam exam;
};
void CalcExamResult (struct Student *stud);
void FindRank (struct Student *stud, struct Student studInfo[10]);
//이렇게 선언해줘여함.
main()
{
struct Student studentInfo[] =
{
{"홍길동", {88, 73, 89, Unident}},
{"일지매", {87, 82, 73, Unident}},
{"심청", {76, 88, 89, Unident}},
{"이몽룡", {57, 45, 67, Unident}},
{"성춘향", {65, 85, 68, Unident}},
{"장화", {85, 75, 98, Unident}},
{"홍련", {96, 68, 63, Unident}},
{"흥부", {44, 65, 58, Unident}},
{"놀부", {76, 69, 77, Unident}},
{"임꺽정", {89, 78, 83, Unident}}
};
//각 학생들의 총점과 평균을 계산.
int student;
for(student = 0; student <10; ++student)
CalcExamResult(&studentInfo [student]);
//student번째 학생의 평균과 총점을 계산하고 합격여부를 가리는 함수.
//포인터로 바꿧으니까 &studentInfo로 변경.
//각 학생들의 총점과 평균을 출력
for (student = 0; student < 10; ++student)
printf("%s : 총점 %d 평균 %f\n", studentInfo[student]. name,
studentInfo[student]. exam .total,
studentInfo[student]. exam .avg);
//합격자들만 출력
puts("합격자들 리스트");
for(student = 0; student < 10; ++student)
if(studentInfo[student].exam.avg > 60)
printf("%s\n", studentInfo[student].name);
//밑에 삼항연산자로 이미 나눈 P/F 사용하기
puts("합격자들 리스트");
for(student = 0; student < 10; ++student)
if(studentInfo[student].exam.result == Pass)
printf("%s\n", studentInfo[student].name);
//등수를 구하는 함수
/*FindRank(&studentInfo[0], studentInfo); //0번 학생의 등수를 구하는 함수.
//전체 학생의 정보를 알고 있어야 등수를 구할 수 있으므로 studentInfo도 전달해야함.
//구조체 변수 안의 정보 (exam.rank)를 바꿔야 하므로 주소로 바꿔 전달해야한다.
FindRank(&studentInfo[1], studentInfo); //1번 학생의 등수를 구하는 함수.
FindRank(&studentInfo[2], studentInfo); //2번 학생의 등수를 구하는 함수.
*/
FindRank(&studentInfo[student], studentInfo);
puts("각 학생 등수 출력");
for(student = 0; student < 10; ++student)
printf("이름 : %s 총점 : %d 등수 : %d\n", studentInfo[student].name,studentInfo[student].exam.total,studentInfo[student].exam.rank);
}
void FindRank (struct Student *stud, struct Student studInfo[10])
{
//내 등수를 1로 간주
int rank =1;
int student;
for(student =0; student < 10; ++student) //모든 학생들의 성적을 비교
if(stud->exam.total /*내성적*/ < studInfo[student].exam.total/*다른학생성적*/)
++rank;
stud->exam.rank =rank; //내 등수 저장.
//나보다 잘하는 학생이 있으면 내 등수가 하나씩 떨어짐.
}
void CalcExamResult (struct Student *stud)
{
//총점과 평균 계산
int total = stud->exam.cLang + stud->exam.java + stud->exam.python;
double avg = total/3.0;
stud->exam.total = total;
stud->exam.avg = avg;
//stud.exam 하면 안돼!
//원래 있던 구조체의 값에 변화가 없기 때문
//그러면 포인터를 쓰자.
//stud.exam 부분을 모두 . 에서->로 변경.
//합격 여부
/*
if (avg>=60)
stud->exam.result = Pass;
else
stud->exam.result = Fail;
*/
//삼항연산자 사용
stud->exam .result = avg >= 60 ? Pass : Fail;
}
댓글
댓글 쓰기