• 검색 결과가 없습니다.

이차방정식 문제: QuadEqProblem

문서에서 객체의 개념, 표현, 사용, 구현 (페이지 49-74)

 "이차방정식 문제" 객체를 위한 자료형

typedef struct {

QuadEquation equation ; Roots r ;

float determinant ;

} QuadEqProblem ;

 main()의 개괄적인 구성은?

void main()

{ QuadEqProblem qeProblem ; // 객체 qeProblem 생성 BOOLEAN solvingRequested ;

OutputMsg_startSolvingQuadEquation() ; // 시작 메시지 출력

solvingRequested = isSolvingRequested() ; // 문제 풀이 여부를 묻고 응답을 얻는다.

while ( solvingRequested ) {

이차방정식의 계수를 입력 받는다 ; 이차방정식을 보여준다 ;

if ( 이차항의 계수가 0 이면 ) {

이차항의 계수가 0 이라는 메시지를 출력한다 ; }

else {

판별식의 값을 계산한다 ; if ( 판별식의 값이 음수이면 ) {

판별식의 값이 음수라는 메시지를 출력한다 ; }

else {

이차방정식을 푼다 ;

이차방정식의 해를 출력한다 ; } }

solvingRequested = isSolvingRequested() ; // 문제 풀이 여부를 묻고 응답을 얻는다.

}

OutputMsg_endSolvingQuadEquation() ; // 종료 메시지 출력 }

 main()에서의 반복 구조

void main()

{ QuadEqProblem qeProblem ; // 객체 생성 BOOLEAN solvingRequested ;

OutputMsg_startSolvingQuadEquation() ;

solvingRequested = isSolvingRequested() ; // 문제 풀이 여부를 묻고 응답을 얻는다.

while ( solvingRequested ) {

이차방정식의 계수를 입력 받는다 ; 이차방정식을 보여준다 ;

if ( 이차항의 계수가 0 이면 ) {

이차항의 계수가 0 이라는 메시지를 출력한다 ; }

else {

판별식의 값을 계산한다 ; if ( 판별식의 값이 음수이면 ) {

판별식의 값이 음수라는 메시지를 출력한다 ; }

else {

이차방정식을 푼다 ;

이차방정식의 해를 출력한다 ; } }

solvingRequested = isSolvingRequested() ; }

OutputMsg_endSolvingQuadEquation() ; }

 한 개의 방정식을 풀기 위한 과정만!

void main()

{ QuadEqProblem qeProblem ; // 객체 생성 BOOLEAN solvingRequested;

OutputMsg_startSolvingQuadEquation() ; solvingRequested = isSolvingRequested() ; while ( solvingRequested ) {

이차방정식의 계수를 입력 받는다 ; 이차방정식을 보여준다 ;

if ( 이차항의 계수가 0 이면 ) {

이차항의 계수가 0 이라는 메시지를 출력한다 ; }

else {

판별식의 값을 계산한다 ; if ( 판별식의 값이 음수이면 ) {

판별식의 값이 음수라는 메시지를 출력한다 ; }

else {

이차방정식을 푼다 ;

이차방정식의 해를 출력한다 ; } }

solvingRequested = isSolvingRequested() ; }

OutputMsg_endSolvingQuadEquation() ; }

 이렇게 할 수는 없을까?

void main()

{ QuadEqProblem qeProblem ; // 객체 생성: 문제 풀이 과정에서 필요한 모든 정보를 소유 BOOLEAN solvingRequested ;

QuadEquation eq ;

OutputMsg_startSolvingQuadEquation() ; solvingRequested = isSolvingRequested() ; while ( solvingRequested ) {

eq = inputQuadEquation() ;

QEP_setEquation(qeProblem,eq ) ; // 객체와 부가정보를 제공 QEP_showEquation(qeProblem) ; // 객체만 제공

if ( QEP_secondCoeffcientZero(qeProblem) ) { // 객체만 제공

QEP_outputMsg_secondCoefficientZero(qeProblem) ; // 객체만 제공 } else {

QEP_calcDeterminant(qeProblem) ; // 객체만 제공

if ( QEP_determinantNegative(qeProblem) ) { // 객체만 제공

QEP_outputMsg_DeterminantNegative(qeProblem) ; // 객체만 제공 } else {

QEP_solveEquation(qeProblem) ; // 객체만 제공 QEP_showRoots(qeProblem) ; // 객체만 제공 } }

solvingRequested = isSolvingRequested() ; } OutputMsg_endSolvingQuadEquation() ;

}

원하는 일을 하는 함수에 제공되는 정보는, 단순히 객체 자체,

(그리고 필요에 따라 객체의 속성이 아닌 부가정보)

 QuadEqProblem과 직결된 함수들은...

void main()

{ QuadEqProblem qeProblem ; // 객체 생성: 문제 풀이 과정에서 필요한 모든 정보를 소유 BOOLEAN solvingRequested ;

OutputMsg_startSolvingQuadEquation() ; solvingRequested = isSolvingRequested() ; while ( solvingRequested ) {

QEP_setEquation(qeProblem, inputQuadEquation()) ; QEP_showEquation(qeProblem) ;

if ( QEP_secondCoeffcientZero(qeProblem) ) {

QEP_outputMsg_secondCoefficientZero(qeProblem) ; }

else {

QEP_calcDeterminant(qeProblem) ;

if ( QEP_determinantNegative(qeProblem) ) {

QEP_outputMsg_determinantNegative(qeProblem) ; }

else {

QEP_solveEquation(qeProblem) ; QEP_showRoots(qeProblem) ; } }

solvingRequested = solvingRequested() ; }

OutputMsg_endSolvingQuadEquation() ; }

이름에 “QEP_”를 붙인 함수는 모두 QuadEqProblem 객체와

직결된 함수들이다.

 문제점은?

void main()

{ QuadEqProblem qeProblem ; // 객체 생성: 문제 풀이 과정에서 필요한 모든 정보를 소유 BOOLEAN solvingRequested ;

OutputMsg_startSolvingQuadEquation() ; solvingRequested = isSolvingRequested() ; while ( solvingRequested ) {

QEP_setEquation(qeProblem, inputQuadEquation()) ; // qeProblem만 제공해서 될까?

QEP_showEquation(qeProblem) ;

if ( QEP_secondCoeffcientZero(qeProblem) ) {

QEP_outputMsg_secondCoefficientZero(qeProblem) ; }

else {

QEP_calcDeterminant(qeProblem) ; // qeProblem만 제공해서 될까?

if ( QEP_determinantNegative(qeProblem) ) {

QEP_outputMsg_DeterminantNegative(qeProblem) ; }

else {

QEP_solveEquation(qeProblem) ; // qeProblem만 제공해서 될까?

QEP_showRoots(qeProblem) ; } }

solvingRequested = isSolvingRequested() ; }

OutputMsg_endSolvingQuadEquation() ; }

 이유는?

QEP_setEquation(qeProblem, InputQuadEquation() ) ; QEP_showEquation(qeProblem) ;

if ( QEP_secondCoeffcientZero(qeProblem) ) {

QEP_outputMsg_secondCoefficnetZero(qeProblem) ; } else {

QEP_calcDeterminant(qeProblem) ;

if ( QEP_determinantNegative(qeProblem) ) {

QEP_outputMsg_determinantNegative(qeProblem) ; } else {

QEP_solveEquation(qeProblem) ; QEP_showRoots(qeProblem) ; } }

문제는, 함수에 매개변수로 주어진 것은:

함수 안에서 사용은 당연히 가능

함수 안에서 그 값을 변경하는 것은 “현재로서는” 불가능

 그러나, (C 언어로) 함수 안에서 객체의 속성 값을 변경할 수 있는 방법이 있 다!!!

 우선은 (어쩔 수 없이 당분간, 정말 그러고 싶지는 않지만)

객체의 구체적인 형태를 main()에서 인식하자!

 "이차방정식" 객체를 위한 자료형

typedef struct { float a ; float b ; float c ;

} QuadEquation ;

a (2차항의 계수) b (1차항의 계수) c (상수항의 계수)

이차방정식: QuadEquation

 "이차방정식의 해" 객체를 위한 자료형

typedef struct { float x1 ; float x2 ;

} Roots ;

x1 (방정식의 해 1) x2 (방정식의 해 2) 방정식의 해: Roots

 "이차방정식 문제" 객체를 위한 자료형

typedef struct {

QuadEquation equation ; Roots roots ;

float determinant ; } QuadEqProblem ;

이차방정식 문제: QuadEqProblem

a (2차항의 계수) b (1차항의 계수) c (상수항의 계수)

이차방정식

x1 (방정식의 해 1) x2 (방정식의 해 2)

방정식의 해

판별식의 값

 main(): "현재로서는 우선" 이렇게

void main()

{ QuadEqProblem qeProblem ; // 객체 생성 BOLEAN solvingRequested ;

OutputMsg_StartSolvingQuadEquation() ; solvingRequested = isSolvingRequested() ; while ( solvingRequested ) {

qeProblem.equation = inputQuadEquation() ; // 어쩔 수 없이 main()에서 객체의 속성 값을 직접 변경 QEP_showEquation(qeProblem) ;

if ( QEP_secondCoeffcientZero(qeProblem) ) {

QEP_outputMsg_secondCoefficientZero(qeProblem) ; }

else {

qeProblem.Determinant = QEP_calcDeterminant(qeProblem) ; // 어쩔 수 없이 main()에서 ...

if ( QEP_determinantNegative(qeProblem) ) {

QEP_outputMsg_determinantNegative(qeProblem) ; }

else {

qeProblem.r = QEP_solveEquation(qeProblem) ; // 어쩔 수 없이 main()에서 ...

QEP_showRoots(qeProblem) ; } }

solvingRequested = solvingRequested() ; }

outputMsg_endSolvingQuadEquation() ; }

 이제 각 함수들을 구현해 보자

 프로그램의 시작과 종료를 알리는 메시지 출력 함수들

OutputMsg_StartSolvingQuadEquation()

OutputMsg_EndSolvingQuadEquation()

 입력과 관련된 함수들

solvingRequested()

inputQuadEquation()

 Class “QuadEqProblem” 과 직결된 함수들

QEP_showEquation()

QEP_secondCoeffcientZero()

QEP_determinantNegative()

QEP_showRoots()

QEP_calcDeterminant()

QEP_solveEquation()

QEP_outputMsg_SecondCoefficnetZero()

QEP_outputMsg_DeterminantNegative()

 isSolvingRequested()

 BOOLEAN isSolvingRequested()

이차방정식 풀이를 할 것인지를 묻는 메시지를 출력

getch()를 사용하여 ‘y’ 또는 ‘n’를 입력 받는다.

입력 받은 것이 ‘y’이면 TRUE, ‘y’가 아니면 FALSE를 return 한다.

간단하게 처리하기 위해, ‘y’가 아닌 것은 모두 ‘n’으로 입력된 것으로 간주 하기로 한다.

코드

BOOLEAN isSolvingRequested() { char answer ;

printf(“방정식을 풀려면 ‘y’, 풀이를 종료하려면 ‘n’을 치시오: “) ; answer = getch() ;

if ( answer == ‘y’) return TRUE ; else

return FALSE ;

}

// 간단하게 이렇게도

return ( answer == ‘y’ ) ;

 계수를 입력 받아서, 이차방정식 객체를 만든다

 QuadEuqation inputQuadEquation()

계수를 입력 받아서, 이차방정식 객체를 만들어 돌려준다.

예:

QuadEqProblem qeProblem ; // 객체 생성 ...

qeProblem.equation = inputQuadEquation() ; // inputQuadEquation() 가 계수를 입력 받아서 // 만들어 돌려준 QuadEquation 자료형의 객체를, // 객체 qeProblem 에 집어넣는다.

 InputQuadEquation()의 구현 코드

QuadEuqation inputQuadEquation()

{

QuadEquatiuon quadEq ;

printf(“2차항의 계수를 입력하시오: “) ; scanf(“%f”, &(quadEq.a)) ;

printf(“1차항의 계수를 입력하시오: “) ; scanf(“%f”, &(quadEq.b)) ;

printf(“상수항의 계수를 입력하시오: “) ; scanf(%f”, &(quadEq.c)) ;

return quadEq ; }

 QuadEqProblem 과 직결된 일을 함수로!

 객체의 상태를 보여주는 것들

QEP_showEquation()

QEP_secondCoeffcientZero()

QEP_determinantNegative()

QEP_showRoots()

 객체의 속성을 가지고 계산하는 것들

QEP_calcDeterminant()

QEP_solveEquation()

 메시지 출력

QEP_outputMsg_secondCoefficientZero()

QEP_outputMsg_determinantNegative

()

QuadEqProblem 과 직결된 함수들:

QuadEqProblem의

“member function” 이라고 한다.

이차방정식 문제

a (2차항의 계수) b (1차항의 계수) c (상수항의 계수)

이차방정식

x1 (방정식의 해 1) x2 (방정식의 해 2)

방정식의 해 판별식의 값

 이차방정식을 보여준다.

void QEP_showEquation(QuadEqProblem qeP)

 이차방정식을 다음과 같은 형태로 보여준다:

 “(2차항의 계수) x*x + (1차항의 계수) x + (상수항의 계수) = 0”

 단, 계수의 값이 0 인 항은 보이지 않게 한다.

모든 계수가 0 이면, “0 = 0”을 출력한다.

// 실수 x 가 0 인지 검사하려면?

float x ;

scanf (“%f”, &x) ;

if ( x == 0.0 ) // 이렇게? 절대로 안됨!!!

---

if ( abs(x) < 0.000001 ) // 반드시 이렇게!

 QEP_showEquation()의 코드

void QEP_showEquation(QuadEqProblem qeP) { BOOLEAN nonZeroTermExist = FALSE ;

if ( abs(qeP.equation.a ) > 0.000001 ) { nonZeroTermExist = TRUE ;

printf(“(%f) x*x”, qeP.equation.a) ; } if ( abs(qeP.equation.b ) > 0.000001 ) { if ( nonZeroTermExist )

printf(“ + “) ;

nonZeroTermExist = TRUE ; printf(“(%f) x”, qeP.equation.b) ; } if ( abs(qeP.equation.c ) > 0.000001 ) { if ( nonZeroTermExist )

printf(“ + “) ;

nonZeroTermExist = TRUE ; printf(“(%f)”, qeP.equation.c) ; } if ( ! nonZeroTermExist )

printf (“0”) printf(“ = 0”) ;

 판별식의 값을 보여준다.

void QEP_showDeterminant(QuadEqProblem qeP)

 판별식의 값을 다음과 같이 보여준다: (값이 4.0 인 경우)

 “>판별식의 값: 4.0”

 방정식의 해를 보여준다

void QEP_showRoots(QuadEqProblem qeP)

 판별식을 계산한다.

float QEP_calcDeterminant(QuadEqProblem qeP)

 주어진 이차방정식 문제에 대해, 이차방정식의 판별식 값 을 계산한다.

 사용 예:

QuadEqProblem qeProblem ; // 객체 생성 ...

qeProblem.determinant = QEP_calcDeterminant(qeProblem) ; // calcDeterminant() 가 계산해 준 판별식의 값을

// 객체 qeProblem에 집어넣는다.

 방정식의 해를 구한다

Roots QEP_solveEquation(QuadEqProblem qeP)

 주어진 문제 qeP에 대해, 이차방정식의 해를 구한다.

 결과는 해(Roots) 객체로 만들어 돌려준다.

 사용 예:

QuadEqProblem qeProblem ; // 객체 생성 ...

qeProblem.r = QEO_solveEquation(qeProblem) ;

 QEP_SolveEquation()의 구현 코드

Roots QEP_solveEquation(QuadEqProblem qeP) {

Roots roots ; float sqrtD ;

sqrtD = sqrt(qeP.determinant) ;

r.x1 = (-qeP.equation.b + sqrtD) / (2.0 * qeP.equation.a) ; r.x2 = (-qeP.equation.b - sqrtD) / (2.0 * qeP.equation.a) ; return roots ;

}

 요약

객체 (Object) 와 클래스 (class)

 클래스는 객체의 자료형으로,

 속성과 멤버함수로 구성된다.

(객체의 자료형인) Class의 구성 요소

 속성 (attribute)

 멤버 함수 (member function)

문서에서 객체의 개념, 표현, 사용, 구현 (페이지 49-74)

관련 문서