C++ 프로그래밍 07 2007년 2학기 전자정보공학대학 컴퓨터공학부
Outline 중간고사 review 동적 메모리 할당 문자열
중간고사 Review 1. 왜 소수점이 나오지 않고 있는지 설명하고, 아래의 프로그램을 고쳐서 평균의 소수점이 제대로 나오게 만들어라. #include <iostream> using namespace std; int main() { int korean = 80; int math = 75; int total; float avg; total = korean+math; avg = total / 2; // avg = (float) total/2; cout<<"total = "<<total<<" avg= "<<avg; return 0; }
중간고사 Review 2. 아래 변수 이름 중 올바르지 않은 이름을 모두 찾으시오. 1) error! 2) 25th_birthday 3) int3 4) i 5) i_like_a_very_long_variable_because_it_is_clearer
중간고사 Review 3. 빈 칸을 채워보자. 1) 1바이트는 ( 8 ) 비트이다. 1) 1바이트는 ( 8 ) 비트이다. 2) 타입의 크기를 알아내기 위해서는 ( sizeof ) 연산자를 사용한다.
중간고사 Review 4. for 문을 사용한 다음 코드의 결과를 예측하고, while문을 사용해서 똑 같은 의미의 코드로 바꾸어라. int sum = 0; for(int i = 1; i<=5; i++) sum += i; cout<<sum; return 0; int i=1; while(i<=5) { i++; }
중간고사 Review 5. 아래 예제 코드에서 잘 못된 부분을 찾고 설명해 보라. int arr[3]; arr[1] = 10; int arr[3]; arr[1] = 10; arr[2] = 20; arr[3] = 30;
중간고사 Review 6. 문자열을 만들어서 출력하려고 아래와 같은 프로그램을 만들었으나, 다음과 같은 에러를 발생시키며 컴파일이 안되고 있다. 에러의 원인은 무엇이고 어떻게 고치면 되는가? Error Code: 7번째 줄: error '=' : 'const char [16]'에서'char [20]'(으)로 변환할 수 없습니다. 프로그램: #include <iostream> using namespace std; int main() { char name[20]; name = "c++ programming"; // char name[] = “c++ programming”; cout<<name; return 0; }
중간고사 Review 3 7. 다음 프로그램을 실행시킨 결과를 예측하라. #include <iostream> #include <iostream> using namespace std; int main() { int arr[5]={0}; int * p = &arr[3]; int * q = &arr[0]; int r1 = p - q; int r2 = *p - *q; cout<<r1<<”\n”; cout<<r2<<”\n”; return 0; } 3
중간고사 Review 8. for문을 사용하여 다음과 같이 구구단을 출력하는 프로그램을 만들려 한다. 빈칸( )을 채워서 프로그램을 완성하라. #include <iostream> using namespace std; void multiplication(int num); void main() { int num; cout<<"숫자를입력하시오:"; cin>>num; multiplication(num); } void multiplication(int num) int i; for (i=1; i<=9; i++ ) cout<<num<<“*”<<i<<“=“<<num*i<<“\n”;
중간고사 Review 9. 함수는 일반적으로 반환값(return value)을 한 개 밖에 가질 수 없으나, 반환값을 여러 개 보내야 할 필요성이 있는 경우가 많이 있다. 수업시간에 반환값이 2개 이상일 경우를 다루는 두 가지 방법에 대해 배웠다. 이 두 가지 방법에 대해 설명하라. Call-by-pointer (*) Call-by-reference (&)
중간고사 Review 10. 팩토리얼(!)은 수학 연산의 일종으로 주어진 값 보다 같거나 작은 모든 양의 정수를 곱하는 것을 의미한다. 즉 5! = 5x4x3x2x1 = 120. 팩토리얼은 재귀함수(Recursive call)의 좋은 예로 많이 쓰이는 데, 즉 5! = 5x4! 의 관계가 있으며, 또한 4!=4x3! 이며 3!=3x2!, 2! = 2x1 이다. 이런 성질을 이용하면 팩토리얼 값을 재귀적으로 구할 수 있다. 팩토리얼 값을 재귀적으로 구하는 아래의 함수 factorial을 완성하라. int factorial (int n) { if(n<=1) return 1; return n * factorial(n-1); }
동적 메모리 할당
메모리 할당(assignment) 컴퓨터 내의 메모리를 확보하는 일 정적(static) 메모리 할당 int a[100] : 100개의 정수공간 확보 (400 byte) 정적(static) 메모리 할당 프로그램 실행 전에 메모리 크기 결정 동적(dynamic) 메모리 할당 프로그램 실행 후에 메모리 크기 결정
정적 할당 vs. 동적 할당 int length = 100; int arr[length]; int length = 100; 배열은 변수를 사용해 크기 지정을 할 수 없다. 동적 할당은 변수를 통해 할 수 있다. int length = 100; int arr[length]; int length = 100; int * arr = new int [length];
기본적인 동적 메모리 할당과 해제(1) 사용자에게 입력 받은 정수의 합과 평균을 구하는 예 int size; cout << “정수 개수: ”; cin >> size; // 필요한 만큼의 메모리를 할당한다. int* arr = new int [size]; cout << "정수를 입력하시오.\n"; for (int i = 0; i < size; i++) cin >> arr[i]; int sum = 0; for (i = 0; i < size; i++) sum += arr[i]; float ave = (float)sum / (float)size; cout <<“합=“<<sum<<“,평균 =“<<ave<<"\n"; // 사용한 메모리를 해제한다. delete[] arr; 사용자에게 입력 받은 정수의 합과 평균을 구하는 예
기본적인 동적 메모리 할당과 해제(2) 동적으로 메모리를 할당하기
기본적인 동적 메모리 할당과 해제(3) [16-7]
기본적인 동적 메모리 할당과 해제(4) 동적으로 할당한 메모리를 해제하기
기본적인 동적 메모리 할당과 해제(5) 동적 메모리 할당을 사용하는 방법의 정리 포인터 선언. int * arr; 메모리를 할당할 때는 타입과 크기를 지정. 컴퓨터가 메모리를 할당한 후에 그 메모리의 주소를 리턴한다. arr = new int[size]; 주소를 통해서 메모리 공간을 사용. 이 때는 배열의 원소를 가리키는 포인터처럼 사용할 수 있다. arr[0]; 사용이 끝난 후에는 반드시 보관해 둔 주소를 알려주면서 메모리를 해제. delete [] arr;
연산자 new, delete, new[], delete[] int* p = new int; // 메모리 1개 할당 *p = 337; // 메모리 접근/사용 delete p; // 메모리 해제 [16-9]
동적 메모리 할당의 규칙(1) new, delete와 new[], delete[] 쌍을 맞춰서 사용하자. 해제한 메모리를 또 해제해서는 안 된다. int * p; p = new int; // 메모리 1개 할당 delete p; // 메모리 1개 해제 p = new int [100]; // 메모리 100개 할당 delete [] p; // 메모리 100개 해제 short* p = new short [100]; // 메모리를 할당한다. delete[] p; // 메모리를 해제한다. delete[] p; // 메모리를 해제한다. Error!
동적 메모리 할당의 규칙(2) NULL 포인터를 해제하는 것은 안전하다 char* p = NULL; delete p; // 혹은 delete[] p char* p = NULL; p = char [100]; delete [] p; p = NULL;
동적 메모리 할당의 응용(1) 문자열을 뒤집어서 복사해주는 함수 char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len - i - 1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original, 8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0; 문자열을 뒤집어서 복사해주는 함수
동적 메모리 할당의 응용(2) 프로그램의 구조
동적 메모리 할당의 응용(3) [16-16] char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0; [16-16]
동적 메모리 할당의 응용(4) [16-16] char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0; [16-16]
동적 메모리 할당의 응용(5) char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0;
동적 메모리 할당의 응용(6) char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0;
동적 메모리 할당의 응용(7) char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0;
동적 메모리 할당의 응용(8) char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0;
동적 메모리 할당의 응용(9) char* ReverseString(const char* src, int len) { char* reverse = new char [len + 1]; for (int i = 0; i < len; ++i) reverse[i] = src[len-i-1]; reverse[len] = NULL; return reverse; } int main() char original[] = "NEMODORI"; char* copy = ReverseString( original,8); cout << original << "\n"; cout << copy << "\n"; delete[] copy; copy = NULL; return 0;
연습 문자열을 한 칸씩 이동하는 함수를 만들라 Input: “Congraturations! ” Output: ”ongraturations! C” ”ngraturations! Co” ”graturations! Con”
문자열
C 스타일과 C++ 스타일의 문자열 C 언어: 문자열 처리 함수를 사용해서 문자열을 처리 C++: 문자열 클래스를 사용
문자열의 길이와 복사 (C style) #include <iostream> #include <cstring> using namespace std; int main() { char src[] = “Sejong University"; int len = strlen(src); // 1. 길이를 잰다 char* dest = new char [len + 1]; // 2. 메모리 할당 strcpy(dest, src); // 3. 문자열 복사 cout << "src = " << src << "\n"; cout << "dest = " << dest << "\n"; delete[] dest; return 0; }
strlen() strlen() 함수를 사용해서 문자열의 길이를 잴 수 있다. [17-4]
strcpy() strcpy() 함수를 사용해서 문자열의 내용을 복사할 수 있다. [17-6] [17-7]
문자열의 결합과 비교 (C style) #include <iostream> #include <cstring> using namespace std; int main() { char str1[20] = "abcde"; char str2[] = "fghij"; strcat(str1, str2); cout<<“str1=“<<str1<<“\n”; if ( strcmp( str1, "abcdefghij") == 0) cout << "str1 and \"abcdefghij\" are identical.\n"; if ( strcmp( "123456", str1) != 0) cout << "\"123456\" and str1 are NOT identical.\n"; return0; }
strcat() strcat() 함수를 사용해서 문자열을 결합할 수 있다. [17-9] [17-10]
strcmp() strcmp() 함수를 사용해서 문자열의 내용을 비교할 수 있다. [17-11] [17-12]
문자열에 대한 정리 문자열은 정보의 한 종류고, 문자열을 저장하기 위해서는 배열을 사용하거나 동적으로 메모리를 할당(포인터사용)할 필요가 있다. C++에서는 문자열의 첫번째 바이트의 주소를 사용해서, 전체 문자열을 지칭한다. 대부분의 경우에 char* 타입의 변수는 문자열을 가리킨다고 생각해도 된다. // p: 문자열을 넣어야 한다. void Function( char* p );
char * 의 의미 #include <iostream> using namespace std; int main() { char c = ‘A’; char s[] = “This is a string”; cout << s <<“\n”; // s의 주소 cout << &s[0] <<“\n”; // s[0]의 주소 cout << c <<“\n”; // c의 값 cout << &c <<“\n”; // c의 주소 return 0; }
C++ 스타일의 문자열 생성 C++ 스타일의 문자열 변수를 생성하는 예 실행 결과 #include <iostream> #include <string> using namespace std; int main() { string s = "C++ Style~"; cout << s << "\n"; return 0; } [17-21]
C++ 스타일의 문자열 생성 string 객체 사용 실행 결과
문자열의 복사 (C++ Style) 대입 연산자(=) 사용 실행 결과 #include <iostream> #include <string> using namespace std; int main() { string src = “Sejong University"; string desc; desc = src; // 문자열 복사 cout << "src = " << src << "\n"; cout << "desc = " << desc << "\n"; return 0; }
문자열의 길이 (C++ Style) string 객체의 맴버함수 size() 사용 #include <iostream> #include <string> using namespace std; int main() { string s1; string s2 = "123"; string s3 = "abcdefg"; cout << "s1 = " << s1.size() << "\n"; cout << "s2 = " << s2.size() << "\n"; cout << "s3 = " << s3.size() << "\n"; return 0; }
문자열의 결합과 비교(1) #include <iostream> #include <string> using namespace std; int main() { string str1 = "abcde"; string str2 = "fghij"; str1 = str1 + str2; if ( str1 == "abcdefghij“ ) cout << "str1 and \"abcdefghij\" are identical.\n"; if ( "123456" != str1 ) cout << "\"123456\" and str1 are NOT identical.\n"; return 0; }
문자열의 결합과 비교(2) 문자열 결합: + 연산자 사용 문자열 비교: ==, != 연산자 사용 [17-26] [17-27]
문자열의 검색 string 객체의 맴버함수 find( ) 사용 #include <iostream> #include <string> using namespace std; int main() { string text = "Napster's pay-to-play service is officially out, " "and we have a review of the now-legit Napster. " "We also size up its companion music player from Samsung."; cout<< text <<“\n”; cout << "Offset of 'official' = " << text.find( "official" ) << "\n"; }
문자열의 일부분 얻기(1) string 객체의 맴버함수 substr( ) 사용 #include <iostream> #include <string> using namespace std; int main() { string path = "c:\\My Document\\Pictures\\33.jpg"; int len = path.size(); string ext = path.substr( len - 3, 3); cout << "extention = " << ext << "\n"; return 0; }
문자열의 일부분 얻기(2) substr() 함수: substr(시작위치, 길이) [17-31]
C 스타일에서 C++ 스타일로의 변환 대입 연산자 사용 char cstyle[] = "Are you a string, too?"; string cppstyle; cppstyle = cstyle; // 변환한다 cppstyle[0] = 'B'; cout << "cstyle = " << cstyle << "\n"; cout << "cppstyle = " << cppstyle << "\n“;
C++ 스타일에서 C 스타일로의 변환(1) String에서 C 스타일의 문자열 주소 얻기: c_str() 맴버함수 사용 c_str() 함수를 통해서 얻은 문자열의 주소는 상수형인 const char* 타입. 따라서, 이 문자열의 내용을 변경하는 것은 불가능. string cppstyle = "Yes, I am."; const char* cstyle = NULL; cstyle = cppstyle.c_str(); cout << "cstyle = " << cstyle << "\n"; cout << "cppstyle = " << cppstyle << "\n";
C++ 스타일에서 C 스타일로의 변환(2) c의 함수 strcpy사용하여 복사 string cppstyle = "Yes, I am."; char* cstyle = new char [ cppstyle.size() + 1]; strcpy( cstyle, cppstyle.c_str() ); cstyle[0] = 'Z'; cout << "cstyle = " << cstyle << "\n"; cout << "cppstyle = " << cppstyle << "\n"; delete[] cstyle;
간단한 문자열의 입력(1) 간단하게 문자열을 입력 받는 예 (문제를 가지고 있다) char cs[20]; // C 스타일 간단하게 문자열을 입력 받는 예 (문제를 가지고 있다) char cs[20]; // C 스타일 string cpps; // C++ 스타일 // 문자열을 입력받는다. cin >> cs; cin >> cpps; cout << "cs = " << cs << "\n"; cout << "cpps = " << cpps << "\n";
간단한 문자열의 입력(2) 앞의 예제의 문제점 준비된 메모리보다 큰 문자열이 입력된 경우 공백을 포함한 문자열
getline() 을 사용한 문자열의 입력(1) char cs[20]; // C 스타일 string cpps; // C++ 스타일 cin.getline(cs, 20); getline(cin, cpps); cout << "cs = " << cs << "\n"; cout << "cpps = " << cpps << "\n"; [17-45]
getline() 을 사용한 문자열의 입력(2) getline() 함수를 C++ 스타일의 문자열과 함께 사용하는 방법 getline() 함수를 C 스타일의 문자열과 함께 사용하는 방법 [17-42] [17-43]
연습 파일의 경로를 입력 받아 디렉터리 부분만 출력 Input: d:\My Library\Temp\Test.jpg Output: d:\My Library\Temp\