1 / 34

C++ 프로그래밍 12

C++ 프로그래밍 12. 2008 년 2 학기 전자정보공학대학 컴퓨터공학부. Outline. 함수. Announcement. 중간고사 : 필기고사 10 월 14 일 ( 화요일 ) 수업시간 Closed Book 문제유형 : 작년 시험 문제 참고 ( 홈페이지에 게시 ) 실습고사 10 월 21 일 ( 화요일 ) 수업시간 Closed Book. 포인터와 레퍼런스의 사용. 반환되어야 하는 값이 2 개 이상일 때 ? 포인터를 사용 레퍼런스를 사용. 포인터 변수를 인자로 전달하기 (1).

Download Presentation

C++ 프로그래밍 12

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ 프로그래밍 12 2008년 2학기 전자정보공학대학 컴퓨터공학부

  2. Outline • 함수

  3. Announcement • 중간고사: • 필기고사 • 10월 14일 (화요일) 수업시간 • Closed Book • 문제유형: 작년 시험 문제 참고 (홈페이지에 게시) • 실습고사 • 10월 21일(화요일) 수업시간 • Closed Book

  4. 포인터와 레퍼런스의 사용 • 반환되어야 하는 값이 2개 이상일 때? • 포인터를 사용 • 레퍼런스를 사용

  5. 포인터 변수를 인자로 전달하기(1) • 나누기를 하여 몫과 나머지를 구한다 void Div_Rem(int a, int b, int div, int rem) { div = a/b; rem = a%b } int main() { int div=0; int rem=0; Div_Rem(23,5, div, rem); cout<<“23 = 5*“<<div<<“+”<<rem<<“\n”; return 0; }

  6. 포인터 변수를 인자로 전달하기(1) • 나누기를 하여 몫과 나머지를 구한다 void Div_Rem(int a, int b, int * pdiv, int * prem) { * pdiv = a/b; * prem = a%b } int main() { int div=0; int rem=0; Div_Rem(23,5, &div, &rem); cout<<“23 = 5*“<<div<<“+”<<rem<<“\n”; return 0; }

  7. 포인터 변수를 인자로 전달하기(2) • 포인터 타입의 인자를 사용해서 함수의 결과 값을 얻어오는 방법의 정리 • 함수의 매개 변수는 포인터 타입으로 정의한다. • 인자를 넘겨줄 때는 결과 값을 담고 싶은 변수의 주소를 넘겨준다. • 함수 안에서 결과를 넘겨줄 때는 매개변수가 가리키는 곳에 값을 넣어준다.

  8. 레퍼런스 변수를 인자로 전달하기(1) • 레퍼런스 변수를 사용해서 함수 밖으로 결과를 전달 void Div_Rem(int a, int b, int& rdiv, int& rrem) { rdiv = a/b; rrem = a%b } int main() { int div=0; int rem=0; Div_Rem(23,5, div, rem); cout<<“23 = 5*“<<div<<“+”<<rem<<“\n”; return 0; }

  9. 레퍼런스 변수를 인자로 전달하기(2) • 레퍼런스 타입의 인자를 사용해서 함수의 결과 값을 얻어오는 방법의 정리 • 함수의 매개 변수는 레퍼런스 타입으로 정의한다. • 인자를 넘겨줄 때는 결과 값을 담고 싶은 변수를 그대로 넘겨준다. • 함수 안에서 결과를 넘겨줄 때는 매개 변수에 값을 넣어준다.

  10. 배열을 인자로 전달하기(1) • 배열 타입의 인자는 실제로는 포인터를 사용해서 전달된다. int main() { char array[20] = "Hello, World!"; UsingArray( array); cout << "In main() : " << array << "\n"; return 0; } void UsingArray(char arr[] ) { cout << "In UsingArray() : " << arr << "\n"; arr[12] = '?'; }

  11. 배열을 인자로 전달하기(2) • 배열을 인자로 전달하는 방법의 정리 • 매개 변수의 타입을 적어줄 때 ‘배열의 원소 개수’는 적지 않는다. • 인자로 넘겨줄 때는 배열의 이름을 넘겨준다. • 인자로 넘어온 배열을 사용할 때는 그냥 평범한 배열을 사용하듯이 하면 된다.

  12. const를 사용한 배열의 보호 • 인자에 const 속성을 부여해서 배열의 내용이 변경되는 것을 막을 수 있다. • UsingArray()가 호출될 때 실행되는 가상의 코드 void UsingArray( constchar arr[] ) { cout << "In UsingArray() : " << arr << "\n"; arr[12] = '?'; // Error } const char* arr = array;

  13. 2차원 배열의 전달 int main() { int array[5][3] = {{ 1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}}; Using2DArray( array); return 0; } void Using2DArray( int arr[][3] ) { for (int i = 0; i < 5; ++i) for (int j = 0; j < 3; ++ j) { cout<<"arr[" << i << “][" << j << "]”; cout<<“=“<< arr[i][j] << "\n"; } }

  14. 기본적인 구조체의 전달 • 두 점 사이의 거리 구하기 struct Point { int x, y; }; int main() { Point a = {0, 0}; Point b = {3, 4}; double dist_a_b = Distance(a, b); return 0; } double Distance(Point pt1, Point pt2) { // 두 점의 거리를 반환한다. (임시로 0을 반환) return 0.0f; }

  15. 기본적인 구조체의 전달 • 구조체 변수를 인자로 전달하는 예 struct Point { int x, y; }; int main() { Point a = {0, 0}; Point b = {3, 4}; double dist_a_b = Distance(a, b); return 0; } double Distance(Point pt1, Point pt2) { // 두 점의 거리를 반환한다. // (임시로 0을 반환) return 0.0f; } [그림 14-32]

  16. 구조체의 전달과 성능 문제(1) • 조금 전의 방식(Call-by-value)으로 구조체 변수를 전달한 경우에 발생하는 성능 문제 • 인자의 내용이 매개 변수에 복사되는 시간이 낭비된다. • 매개 변수의 크기가 커지므로 메모리가 낭비된다. • 레퍼런스 변수를 사용해서 넘기면 위의 문제를 해결할 수 있다. double Distance( Point& p1, Point& p2) { // 중간 생략 // return 0.0; }

  17. 구조체의 전달과 성능 문제(2) • 레퍼런스로 넘긴 경우에 인자의 값이 바뀔 염려가 있으므로 const 속성을 사용해서 인자를 보호할 필요가 있다. • 구조체 변수를 인자로 전달하는 방법의 정리 • 구조체를 인자로 넘겨줄 때는 레퍼런스를 사용하자. • 함수의 안쪽에서 구조체의 내용을 읽기만 한다면 const와 레퍼런스를 사용하자. double Distance( constPoint& p1, const Point& p2)

  18. CRT 함수의 사용 #include <iostream> #include <cmath> using namespce std; // 중간 코드 생략 double Distance(const Point& p1, const Point& p2) { // 피타고라스의 정리를 사용한다. double distance; distance = sqrt( pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) ); // 결과를 반환한다. return distance; } [그림 14-36]

  19. 함수2

  20. 오버로딩(Overloading) • 같은 이름의 함수들이지만 인자의 형태가 다른 경우 각각에 대해 할 일을 지정한다! 여러가지 다른 일 하나의 함수이름

  21. 오버로딩(Overloading) • 오버로딩을 사용해서 두 가지 버전의 max() 함수를 만드는 예 • 오버로딩을 사용할 수 없다면 서로 다른 이름의 함수를 만들어서 사용해야 한다. int max( int a, int b ); float max( float a, float b ); int max_i( int a, int b ); float max_f( float a, float b );

  22. 기본적인 오버로딩의 규칙 • 인자의 타입을 통해서 호출될 함수를 결정한다. int VariableReturnType( char c, int i ); // 1번 double VariableReturnType( char c, double d ); // 2번 ... VariableReturnType( ‘A’, 100 ); // 1번 함수 호출 VariableReturnType( ‘A’, 100.12 ); // 2번 함수 호출

  23. 기본적인 오버로딩의 규칙 • 반환 값만 틀린 경우는 오버로드 할 수 없다. • 인자가 다르더라도 오버로드 할 수 없는 경우 int VariableReturnType( char c, int i ); double VariableReturnType( char c, int i ); // Error ... VariableReturnType( ‘A’, 100 ); // 어느 것을 호출해야 할 지 모름 void SameSignature( int i ); void SameSignature( int& r ); ... int i = 10; SameSignature( i ); // 어느 것을 호출해야 할 지 모름

  24. 적당한 함수를 찾는 순서 • 오버로드 된 여러 버전의 함수 중에서 알맞은 함수를 찾는 순서 • 1. 정확하게 일치하는 경우(Exact Match) • 2. 승진에 의한 형변환(Promotion) • 3. 표준 형변환(Standard Conversions) • 4. 사용자에 의한 형변환(User-defined Conversions) void WhichOne( float f ); // 1순위 (exact match) void WhichOne( double d ); // 2순위 (promotion) void WhichOne( int c ); // 3순위 (standard conversions) int main() { WhichOne( 3.5f ); return 0; }

  25. 디폴트 인자 • 디폴트 인자를 사용하는 예 bool SetFramesPerSec(int fps = 10) { // 코드 생략 return true; } int main() { // 인자 없이 함수를 호출한다. SetFramesPerSec(); return 0; }

  26. 디폴트 인자를 사용하는 규칙 • 디폴트 인자들은 오른쪽 끝에 모여 있어야 한다. // 올바름: 디폴트 인자 c는 오른쪽에 있다. void DefaultArgs2( int a, int b, int c = 3 ); // 올바름: 디폴트 인자 b, c는 오른쪽에 모여있다. void DefaultArgs1( int a, int b = 2, int c = 3 ); // 틀림: void DefaultArgs3( int a = 1, int b = 2, int c ); void DefaultArgs4( int a = 1, int b, intc = 3 ); void DefulatArgs5( int a = 1, int b, int c);

  27. 디폴트 인자를 사용하는 규칙 • 오버로딩과 디폴트 인자의 충돌하는 경우를 주의해야 한다. void Ambiguous( int a, int b = 100 ); // 1번 void Ambiguous( int a ); // 2번 ... Ambiguous( 50 ); // 어느 것?

  28. 재귀 호출(Recursion)(1) • 자기가 자신을 호출하는 것

  29. 재귀 호출(Recursion)(1) • 재귀호출의 예 • void RecursiveCall() • { • RecursiveCall(); • } • int main() • { • RecursiveCall(); • }

  30. 재귀 호출(Recursion)(2) • 재귀호출의 예 • void WhildPositive(int n) • { • cout<<n<<“\n”; • if(n<0) return; • WhilePositive(n-1); • } • int main() • { • WhildPositive(int n) • }

  31. 재귀 호출(Recursion) 연습 • 재귀 호출을 사용해서 팩토리얼 값을 구하라 1! = 1 2! = 2*1! 3! = 3*2! 4! = 4*3! 5! = 5*4! … 1! = 1 2! = 2*1 3! = 3*2*1 4! = 4*3*2*1 5! = 5*4*3*2*1 …

  32. 재귀 호출(Recursion) 연습 • 재귀 호출을 사용해서 팩토리얼 값을 구하라 • int Factorial(int n) • { • if(n<=1) return 1; • return n*Fartorial(n-1); • } • int main() • { • Factorial(5); • }

  33. 함수 포인터 • 함수 포인터를 사용해서 함수를 가리키는 예 void Dog() { cout << "I'm a dog.\n"; } void Cat() { cout << "I'm a cat.\n"; } int main() { void (*p)(); p = &Dog; (*p)(); p = &Cat; (*p)(); return 0; } [15-10]

  34. 함수 포인터의 정의 • 함수 포인터 타입의 변수를 정의하는 방법

More Related