1 / 44

Computer Graphics (Part 1: C/C++ Programming)

Computer Graphics (Part 1: C/C++ Programming). HyunKi Hong Dept. of Image Eng., GSAIM ChungAng Univ. Contents. 상수와 변수 수식과 연산자 제어 명령문 파생자료형 ( 배열 , 포인터 , 구조체 등 ) C++ 함수 (Part 4 참조 ) 클래스와 객체. 함수 (function). C/C++ 언어는 함수의 집합. 매개변수 (parameter), 인자 : 함수에 입력시키는 것. 함수

ormand
Download Presentation

Computer Graphics (Part 1: C/C++ Programming)

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. Computer Graphics(Part 1: C/C++ Programming) HyunKi Hong Dept. of Image Eng., GSAIM ChungAng Univ.

  2. Contents 상수와 변수 수식과 연산자 제어 명령문 파생자료형(배열, 포인터, 구조체 등) C++ 함수(Part 4 참조) 클래스와 객체

  3. 함수(function) • C/C++언어는 함수의 집합 매개변수(parameter), 인자 :함수에 입력시키는 것 함수 (printf, 사용자가 만든) void:값을 리턴하지 않는 함수 리턴값(return value) : 함수가 돌려주는 결과 값 표준 라이브러리 함수 (standard library function)

  4. 함수의 기본 개념 • 필요한 자료를 입력받아 임의의 처리한 후 결과를 되돌려주는 부프로그램 • 호출에 의해 일정 행위를 하고 그 결과를 보고하는 기능 단위 • 다른 언어의 subroutine의 개념과 비슷 • 모듈화 프로그램 가능 : 적절한 함수를 만들어 필요할 때마다 호출/사용 • main()함수, 라이브러리(표준)함수, 사용자정의함수 등으로 구분

  5. C/C++언어의 함수 종류 • main함수 • 한 프로그램에 반드시 하나 존재 • 제일 먼저 실행되는 함수 • 사용자 정의 함수 • 사용자가 작성한 함수 • main함수나 다른 함수에 의해 호출됨 • 표준 라이브러리(library)함수 • header 파일(stdio.h, stdlib.h 등)에 선언되어 있음 • printf, scanf, getchar 등

  6. main 함수 • C프로그램에 반드시 있어야 하는 함수 • 한 프로그램에 하나만 있어야 함 • 제일 먼저 실행되는 함수

  7. 표준 라이브러리 함수(standard library function) • 화면에 출력하는 함수를 프로그래머가 일일이 만들어야 하나? • 프로그래머를 위해서 만들어져 있는 함수 • 사용하기 전에 반드시 선언해야 함 • printf()라는 함수를 사용하려면 먼저 선언해야 함 • 선언하는 방법은 2가지 • 이 함수가 선언되어 있는 stdio.h라는 파일(표준헤더파일)을 프로그램에 포함시킴 : #include <stdio.h> • 직접 선언함: int printf(const char *, ...);

  8. 표준 헤더 파일(standard header file) • 라이브러리 함수들을 미리 선언해 놓은 파일 • 함수들을 기능별로 분류하여 정리해놓음 • printf, scanf는 stdio.h에 선언(원형)이 들어 있음 • Microsoft Visual Studio/VC98/include/*.h • 약 400여개의 .h가 있음(C 경우)

  9. 사용자 정의 함수 • 기본 명령이나 표준 함수 조합으로 원하는 처리할 수 없는 경우 void main() { float list[50]; readlist(list); sort(list); average(list); bargraph(list); } 숫자를 읽어 들인다. 숫자들을 정렬시킨다. 평균을 구한다. 막대 그래프를 그린다. 서술적인 함수명칭 사용해 기능, 구조 등을 알기 쉽게 모듈화, 재사용 가능, 공동 작업시 편리

  10. 함수의 정의 [return할 데이타형] 함수명(자료형1 인수1, 자료형2 인수2) { // 함수 블록의 시작 함수 안에서 사용하는 변수 선언; 실행문; // 처리 명령어들이 위치 return(함수값); // 반환되는 합수값이 있는 경우 필요 } // 함수블록의 끝 매개변수가 있으면 각 매개변수의 형을 쓰고 개수 만큼 컴마로 구분 함수 정의

  11. 함수와 반환값 • 함수는 한 개의 값만을 반환 • 반환값이 있는 경우, 함수 이름 앞에 반환되는 값의 자료형을 명시(반환값이 없는 경우, void 표시) • 함수본체에는 return() 함수 통해 값을 반환 int sum(int x, int y); 함수 선언:함수의 헤더 만으로 한 문장을 만듬 int sum(int x, int y) { int z; z=x+y; return(z); } 함수 정의 return(x+y);

  12. 함수의 인수(매개변수) 전달 • 함수들 간에 서로 데이터를 교환할 때 • 매개변수 전달 방법 • 값에 의한 호출(call by value) : C에서 기본 • 참조(주소)에 의한 호출(call by reference)

  13. 함수의 호출(1) • main() 함수에서 다른 함수를 호출하면, 프로그램 실행 제어가 호출된 함수로 넘어가 실행된 후, return문 만나면 실행 제어가 복귀되어 다시 main() 함수 실행됨. void main(void) { int a; display(); a = sum(3, 4); cout << a << endl; } #include <iostream.h> void display(void) { cout << "함수값이 없는 함수입니다.\n"; } int sum(int x, int y) { return(x+y); } 함수값과 가인수 없음. 당연히 return문 없음. 13/44

  14. 함수의 호출(2) #include <iostream.h> double reverse(int x, int y) { if(x == y && x == 0) return(0); else if(x>=y) return(1.0/(x+y)); else return(1.0/(y-x)); } void main(void) { cout<<reverse(3, 5)<<" : "<< reverse(5, 3)<< ":"<< reverse(5, 5)<<":"<<reverse(0, 0)<<endl; } 14/44

  15. #include <iostream.h> int myfunction(int, float); void main(void) { …… myfunction(3, 4.0); …… } // End of the main() int myfunction(int x, float y) { …… } // End of the myfunction() #include <iostream.h> void main(void) { int myfunction(int, float); myfunction(3, 4.0); …… } // End of the main() int myfunction(int x, float y) { …… } // End of the myfunction() “함수 호출 이전에 함수 선언” 만족. 하지만 옆 프로그램과는 차이점 존재 함수의 원형(prototype) 선언(1) • 함수는 호출되기 전에 반드시 먼저 선언 • 함수를 main() 함수 뒤에 정의하면, 컴파일러에게 함수 존재를 알려주어야 함. • 함수의 원형을 함수 호출이전에 선언: 함수원형 선언(선언문 성격이므로 ‘;’ 사용)

  16. 정의(definition)와 선언(declaration) • 정의(선언을 겸한다) • 만든다. • 변수나 함수의 특성을 완전하게 지정해 주어야 함. • 변수나 함수를 위한 저장장소를 메모리에 할당. • 내부구조를 모두 보여준다. • 선언 • 알린다. • 기본 사용법 • 변수나 함수의 특성을 컴파일러에게 알려 주기만 함. • 사용 방법만 알려준다(이름, 입력, 출력)

  17. 함수의 원형(prototype) 선언(2) • 함수 호출 이전에 함수 원형의 선언이 생략되면, ‘선언되지 않은 식별어(undefined identifier)’ 오류 발생 • 함수 원형 선언시, 인수 리스트에 인수에 해당하는 자료형만을 나열해도 인식 가능 : (1) • 자료형과 함께 인수 이름까지 명시하면 프로그램 이해에 유리 : (2), (3) (1) int myfunction(int, float); (2) int myfunction(int x, float y); (3) int myfunction(int a, float b); 인수의 실제이름은 중요하지 않음.

  18. 인수의 전달방법(1): 값에 의한 호출(Call by vale) • 호출 함수에서 변수 또는 객체의 값만을 전달. 즉, 호출함수의 실인수 값이 단순 복사되어 피호출 함수의 가인수에 전달 • 실인수와 가인수는 서로 다른 독립적인 변수나 객체 #include <iostream.h> int sqr(int); // 함수원형 main(void) { int result, x; x = 10; result = sqr(x); cout << x << "," << result << endl; } int sqr(int x) { x++; return(x*x); } 실인수 값은 여전히 10 (가인수와 무관) 가인수 값을 의도적으로 수정 18/44

  19. call by value 예제 1 #include <iostream.h> int sum(int x,int y); void main() { int a=2,b=5,c; c=sum(a,b); //실제로는 이렇게 호출함 sum(2,5); cout<<c; } int sum(int x, int y) { return(x+y); } c=sum(a, b); 실매개 변수 변수의 실제 값 전달 int sum(int a, int b) { return(a+b); } 형식매개 변수 x로 a가 대입되는 것이 아님 a의 실제 값인 2가 대입됨 19/44

  20. call by value 예제 2 #include <iostream.h> int sum(int x,int y); //int sum(int, int); void main() { int a=2, b=5, c; c=sum(a,b); cout<<a<< b<<c; //2,5,14 } int sum(int a,int b) //a에 2, b에 5가 넘어옴 { a+=2; //여기의 a와 main함수의 a는 전혀 다른 변수임 b+=5; cout<<a<<b; return(a+b); } 20/44

  21. 인수의 전달방법(2): 주소에 의한 호출(Call by address) • 호출 함수에서 피호출 함수로 변수 또는 객체의 포인터를 전달하는 방법 • 실인수는 변수의 주소값이 되고, 가인수는 이 주소를 받을 수 있는 포인터 변수 #include <iostream.h> int facto(int, int *); // 함수원형 main(void) { int n, count = 1; cin >> n; cout << "함수 호출 전 count 값 = " << count << endl; cout << "Fractorial of " << n << " : " << facto(n, &count) << endl; cout << "함수 호출 후 count 값 = " << count << endl; } int facto(int x, int *fac) { int i = 1; while(i++ < x) *fac *=i; return(*fac); } 주소값을 전달 → 실인수 count와 가인수 fac은 동일한 기억장소의 주소값을 공유 가인수 값 변경 → 호출함수의 실인수 값 변경 21/44

  22. call by reference • 실매개변수의 주소를 피호출 함수의 변수인 형식매개변수로 전달 • 형식매개변수가 변하면 실매개변수도 변함 • return 값이 여러 개이거나 배열 전체를 전달하는 경우 사용 • 함수 호출할 때 : swap(&a, &b) • 함수 정의 시 : swap(int *a, int *b)

  23. call by value vs. call by reference #include <iostream.h> void swap(int *, int *); void main() { int a=2,b=5; cout<<a<<b<< '\n'; swap(&a,&b); cout<<a<<b<< '\n'; } void swap(int *pa, int *pb) { int temp; temp=*pa; *pa=*pb; *pb=temp; cout<<*pa<<*pb<< '\n'; } #include <iostream.h> void swap(int, int); void main() { int a=2,b=5; cout<<a<<b<<'\n' ; swap(a,b); cout<<a<<b<< '\n'; } void swap(int a,int b) { int temp; temp=a; a=b; b=temp; cout<<a<<b<< '\n'; } 실매개변수를 주소로 전달 형식매개변수가 포인터 변수 23/44

  24. call by reference 예제 #include <iostream.h> void ss(int, int, int*, int*); void main() { int a=2,b=5; int sum,sub; cout<<sum<<sub<<‘\n’; //쓰레기 값 ss(a,b,&sum,&sub); cout<<sum<<sub<<‘\n’; //7 -3 } void ss(int a,int b, int*psum, int *psub) { *psum=a+b; *psub=a-b; } SS()함수를 호출 후 변화되는 값은 2개 SS()함수는 리턴값이 없지만 실제로는 2개의 값이 리턴되는 것과 같은 효과 main()의 sum변수의 주소를 받는 포인터 변수 24/44

  25. call by reference 2가지 방법 #include <iostream.h> void swap(int *, int *); void main() { int a=2,b=5; cout<<a<<b<< '\n' ; swap(&a,&b); cout<<a<<b<< '\n'; } void swap(int *pa, int *pb) { int temp; temp=*pa; *pa=*pb; *pb=temp; cout<<*pa<<*pb<< '\n'; } #include <iostream.h> void swap(int &, int &); void main() { int a=2, b=5; cout<<a<<b<< '\n'; swap(a,b); cout<<a<<b<< '\n'; } void swap(int &ra, int &rb) { int temp; temp=ra; ra=rb; rb=temp; cout<<ra<<rb<< '\n'; } 포인터를 사용하는 방법 참조자를 사용하는 방법 25/44

  26. 구조체 변수의 매개변수 전달 call by value call by reference #include <stdio.h> struct score{ int kor, eng; }; int hap(score hkd); void main() { score jumsu={80,90}; int sum; sum=hap(jumsu); printf("%d",sum); } int hap(score hkd) { return(hkd.eng+hkd.kor); } #include <stdio.h> struct score{ int kor, eng; }; int hap(score *hkd); void main() { score jumsu={80,90}; int sum; sum=hap(&jumsu); printf("%d",sum); } int hap(score *hkd) { return(hkd->eng+hkd->kor); } 26/44

  27. 인수의 전달방법(3): 참조에 의한 호출(Call by reference) • 피호출 함수의 가인수를 참조자(reference)로 선언하고 호출함수에서 실인수로 변수 이름만 쓰면, 호출함수의 실인수 사용 가능 • 실인수와 가인수는 서로 다른 독립적인 변수나 객체 #include <iostream.h> void swap(int &, int &); void main(void) { int a = 3, b = 7; cout << "a =" << a << ", b =" << b << endl; swap(a, b); cout << "a =" << a << ", b =" << b << endl; } void swap(int &x, int &y) { int temp; temp = x, x = y, y = temp; } 가인수(x, y)는 실인수에 대한 참조자가 되어 가인수를 통해 실인수를 간접적으로 조작 가능 27/44

  28. 인수의 전달방법 예제 #include <iostream.h> void Callvalue(int x, int y) // 일반 가인수 { cout << "Value : " << x++ << ", " << y++ << endl; } void Calladdress(int *x, int *y) // 포인터형 가인수 { cout << "Addess : " <<(*x)++ << ", " << (*y)++ << endl; } void Callreference(int &x, int &y) // 참조형 가인수 { cout << "Reference : " << x++ << ", " << y++ << endl; } void main(void) { int a = 3, b = 4; Callvalue(a, b); Calladdress(&a, &b); Callreference(a, b); cout << "최종값 : " << a << ", " << b << endl; } 28/44

  29. 객체지향 프로그래밍의 등장 배경 • 소프트웨어 위기(software crisis) - 컴퓨터 기술 발전에 따른 소프트웨어 기능 요구가 다양화 a. 프로그램(소프트웨어)의 대형화 및 복잡화 b. 새로운 프로그램의 개발에 많은 노력과 비용 소비 c. 작성 프로그램 관리 및 수정하는 유지보수가 복잡  프로그램 설계/구현시 효율이 떨어지고 생산성이 낮아진다. - 컴퓨터를 구성하는 하드웨어와 소프트웨어의 비용 a. 1960년대 약 4 : 1 정도 b. 1980년 이후 약 90%를 소프트웨어 비용이 차지 • 소프트웨어를 효율적으로 설계/구현하는 방법론 필요

  30. 구조적 프로그래밍(structured programming) 언어 • Divide and Conquer(나누어 정복) • 프로그램의 각 부분을 독립적인 여러 모듈(module)로 나누어 작성 • Pascal, C와 같은 언어 • 처리 동작(명령,연산)에 중점을 두어 프로그램을 작성 • 자료가 프로그램 전체에 노출 • 자료와 처리 동작을 별도로 구분하여 처리동작과 자료 사이의 관계가 서로 밀접한 연관성을 갖지 못함. • 프로그램이 복잡해지면 디버깅 및 유지보수가 어려워짐.

  31. 구조적 프로그래밍 자료 자동차, 차, 사과, 물건, 배 처리동작 소유하다 타다 먹다 읽다 맛있다 객체 지향 프로그래밍 물건 자동차 사과 책 배 소유하다 타다 먹다 읽다 맛있다 구조적 프로그래밍 기법과 객체지향 프로그래밍 • 객체 지향 프로그래밍 - 구조적 프로그래밍 기법을 계승하고 보다 발전시킨 개념 - 자료와 처리동작을 하나로 묶어 다루는 객체(object)개념 도입 - 소프트웨어 확장(extensibility) 및 재사용(reusability) 기회 증가

  32. 클래스 클래스 개 개 객체 객체 객체 객체 객체 객체 멍멍이 해피 메리 멍멍이 해피 메리 클래스 vs. 객체 int int x int y int z

  33. 캡슐화(encapsulation), 다형성(polymorphism), 상속성(inheritance) • 외부간섭, 오용으로부터 코드, 자료를 안전하게 유지 • 서로 다른 자료형을 처리하는 같은 이름의 함수 정의 가능, 함수 다중정의(overloading)라고 함. • 한 객체가 다른 객체의 특성을 이어받는 과정=파생 클래스가 기본 클래스의 정의된 속성(자료, 연산)을 상속받는 것 • 파생 클래스(derived class), 자식 클래스(child class) : 상위 클래스의 속성을 상속받은 하위 클래스 • 기본 클래스(base class), 부모 클래스(parent class) : 상위 클래스

  34. 자료 자료 연산(함수) = + 연산(함수) 객체 객체 = 프로그램 + 객체(object) • 객체는 자료와 이를 처리하는 동작인 연산(함수, method)을 하나로 묶어 만든 요소 • 프로그램을 구성하는 실체 • 객체란 자료를 표현하는변수만을 가지는 것이 아니라 그 객체가 무엇을 할 수 있는가를 정의한함수도 구성 • 인스턴스(Instance) • 어떤 클래스에서 생성된 객체 혹은 한 클래스에 속하는 각각의 객체

  35. 클래스(class) • 객체지향 프로그래밍의 특성인 캡슐화, 다형성, 상속성을 제공하는 사용자 정의 자료형 • 자료의 특성(attribute)과 상태(state)를 나타내는 기본 자료들과 그 자료들의 처리방법을 포함 • 클래스는 유사한 객체들이 갖는 공통된 데이터와 함수들을 정의한 객체의 기본 규격(specification)이다. • 클래스 구성하는 변수와 함수: 클래스의 멤버자료와 멤버함수 변수 함수

  36. 클래스 선언(declaring a class) 예약어 클래스 내부/외부에서의 접근특성 결정 class클래스명{ // class라는 keyword 사용 속성: // private이나 public, protected가 올 수 있음 // private: 비공개 멤버 자료 및 함수 // protected: 보호 멤버 자료 및 함수 // public: 공개 멤버 자료 및 함수 자료선언; // 멤버변수 속성: // 생략하면 private 함수선언; // 멤버함수 } 객체변수; // 객체를 만드는(정의) 첫 번째 방법 클래스명 객체변수; // 객체를 만드는 두 번째 방법

  37. 클래스 선언 예 class Date { private : int year, month, day; // 비공개형 멤버자료 public : void setdate(int yy, int mm, int dd) // 공개형 멤버함수 { year = yy; month = mm; day = dd; } void display() { cout << year << . << month << . << day; } }; 비공개형 자료들에 접근 가능 멤버자료는 자료 은닉 위해 비공개형으로 정의, 변수 설정/출력 위한 함수는 외부에서 접근하도록 공개형으로 정의

  38. 객체 정의 • 객체: 정의된 클래스형에 대해 선언된 변수로 클래스의 구체적 표현이며 그 실체를 의미 • 클래스 이름으로부터 객체를 직접 정의 Date 클래스의 객체 정의 → Date birthday2, wedday2; //Date 클래스형 객체 변수 정의 : 새로운 자료형 cf. int birthday1, wedday1; // int 형 변수 선언 형태가 서로 유사

  39. 클래스 멤버의 호출 • 객체의 공개된 멤버 자료나 함수를 호출할 때 객체이름 다음에 ‘.’ 와 멤버자료 또는 이름 Date birthday; birthday.setdate(2005, 11, 3); birthday.display(); 멤버결합 연산자

  40. 멤버함수의 정의방법 • 일반함수와 같이 멤버함수들도 클래스 정의부 내부에는 해당 멤버 함수의 원형만 쓰고 클래스 외부에 멤버 함수 정의부 작성 가능 → 어느 클래스에 속한 멤버 함수를 알리기 위해 클래스 이름과 영역지정 연산자 ‘::’ 사용 함수값형 소속 클래스 이름::멤버함수이름(인수 리스트) { … // 함수 정의 }

  41. 클래스 선언부 외부에서 멤버함수의 정의방법 class Date { private : int year, month, day; // 비공개형 멤버자료 public : void setdate(int yy, int mm, int dd) // 공개형 멤버함수 void display() }; void Date::setdate(int yy, int mm, int dd) { year = yy; month = mm; day = dd; } void Date::display() { cout << year << “ .” << month << “ .” << day; } 공개형 멤버함수 원형만 소개 멤버함수 실제 정의 : 함수 정의부 길이가 길어지면 이와 같이 정의

  42. 생성자(constructor) • 생성자(클래스 객체가 생성될 때 수행) - 함수의 반환형을 쓰지 않고 클래스 이름과 같은 이름의 함수를 클래스 공개지역(public)에 정의하는 멤버함수 - 전달 인수나 정의 등은 일반 함수와 동일 - 반환값이 없기 때문에 함수 본체 내에 return문이 없음. - 객체 생성시, 임의 값으로 초기화 등을 수행 class Date { private : int year, month, day; public : Date (int yy, int mm, int dd); }; Date::Date(int yy, int mm, int dd) { year = yy; month = mm; day = dd; cout << “Date 객체가 생성됩니다.\n”; }

  43. 소멸자(destructor) • 소멸자(객체 사용이 끝났을 때 수행되는 멤버 함수) - 클래스 이름과 같은 이름을 쓰되 그 앞에 ‘~’ 사용 - 생성자와는 달리 각 클래스는 단 한 개의 소멸자만 가지며, 전달인수를 갖지 않음. - 클래스의 공개 지역(public)에 선언되는 멤버 함수 - 반환값이 없기 때문에 함수 본체 내에 return문이 없음. class Date { private : int year, month, day; public : ~Date (); }; Date::~Date() { cout << “Date 객체가 소멸됩니다.\n”; }

  44. 객체 소멸 순서 void Date::SetDate(int yy, int mm, int dd) { year = yy; month = mm; day = dd; cout << year << "." << month << "." << day ; cout << ": 로 변경되었습니다.\n"; } void Date::Display() { cout << year << "." << month << "." << day << ": 입니다.\n"; } void main() { Date d1(1111, 11, 11), d2(2222, 22, 22), d3(3333, 33, 33); d2.SetDate(1234, 12, 34); d3.Display(); } #include <iostream.h> class Date { private : int year, month, day; public : Date (int yy, int mm, int dd); ~Date(); void SetDate(int yy, int mm, int dd); void Display(); }; Date::Date(int yy, int mm, int dd) { year = yy; month = mm; day = dd; cout << year << "." << month << "." << day ; cout << ": Date 객체가 생성됩니다.\n"; } Date::~Date() { cout << year << "." << month << "." << day ; cout << ": Date 객체가 소멸됩니다.\n"; } 컴파일러가 소멸자 호출하면서 생성된 객체를 역순으로 소멸 44/44

More Related