The C++ Programming Language 5 장포인터, 배열, 구조체 5.9 연습문제 5.9.1 다음의선언문을순서대로작성해보자. 문자에대한포인터, 10개정수의배열, 10개정수의배열의참조자, 문자열의배열에대한포인터, 문자에대한포인터에대한포인터, 상수정수, 상수정수에대한포인터, 정수에대한상수포인터. 그리고각각의객체를초기화하자. Ex 문자에대한포인터 char *p; // 문자에대한포인터선언 char a; p = &a; // 초기화 10개정수의배열 int a[10] = 1, 2, 3, 4 // 10개정수의배열선언과초기화 10개정수의배열의참조자 int a[10] = 3,4,5; int*& b = a; /* 배열의이름은포인터이므로포인터를참조하면된다 */ cout<<a[0]<<a[1]<<a[2]; //345 cout<<b[0]<<b[1]<<b[2]; //345 문자열의배열에대한포인터 char a[ ] = "nclab"; // 문자열 char *b = a; // 배열의이름은포인터이므로 문자에대한포인터에 char a = 'n'; // 문자 대한포인터 char *b = &a; // 문자에대한포인터 char **c = &b; // 포인터의포인터 상수정수 const int a = 1; 상수정수에대한포인터 const int a = 1; // 상수 const int *b = &a; // 상수정수를가리키는포인터 *b = 2 // 상수를바꾸려했으므로 Error b = c //(c는정수포인터 ) 포인터자체는상수가아님 OK! 정수에대한상수포인터 int a = '1'; int *const b = &a; // 포인터자체가상수 *b = 2 // 가리키는정수를값을변경 OK! b = c //(c는정수포인터 ) 상수인포인트변경불가! Error
5.9.2 여러분이사용하는구현환경에서는포인터타입 char*, int*, void* 에대해사용상의어떤제약이있는지조사해보자. #include <iostream> using namespace::std; int main ( ) char c[5] = "What"; char* cp = c; //char 포인터 cout<<&cp<<" "<<&cp+1<<endl; // 메모리주소가 4만큼차이남 int b[5] = 5,6,7,8,9; int* bp = b; //int 포인터 cout<<&bp<<" "<<&bp+1<<endl; // 메모리주소가 4만큼차이남 short int x = 3; short int* sip = &x; //short int 포인터 void* vp = &x; //short int 를가리키는 void포인터 cout<<sizeof(x)<<endl; // short int 의크기는 2 cout<<*sip<<" "<<sizeof(*sip)<<endl; // 가리키는객체의값과크기 cout<<*vp<<" "<<sizeof(*vp)<<endl; //Error : 역참조할수없다.
5.9.8 여러분이사용하고있는컴파일러가포인터를사용한배열순회와색인을 사용한배열순회에대해동일한코드를만들어내는지알아보기위해시험프로그램을몇개실행해보자. #include <iostream> using namespace std; void fi(char v[]) // 색인번호로순회하는함수 for (int i = 0; v[i]!= 0 ; i++) // 색인번호를증가시킴 v[i]++; /* 순회확인을위해글자에 1을더함 (a->b, b->c) 알파벳을증가시킴 */ void fp(char v[]) // 포인터로순회하는함수 for (char* p = v; *p!=0; p++) // 주소값을증가시켜다음글자를가리킴 *p= *p -1; /* 순회확인을위해글자에 1을뺌 (b->a, c->b) 알파벳을감소시킴 */ int main() char ex[] = "apple"; cout<<ex<<endl; // 초기값 apple fi(ex); cout<<ex<<endl; // bqqmf ( 배열순회가이루어지면서 +1이되었음 ) fp(ex); cout<<ex<<endl; //apple로돌아옴 ( 순회하면서다시 -1) /* 어떤방법이든똑같다. */ return 0;
5.9.12 어떤 string 안에들어있는글자쌍의출현빈도를세는함수를하나만들고, char의배열에대해동일하게동작하는함수를하나더만들자. char 배열을이용 Solution 1 #include <iostream> using namespace std; int CountLength (char *s) // 문자열의길이를세는함수 int length = 0; for (char* p = s; *p!= 0; p++) length++; return length; // 순회하면서길이를파악한다. int CountChar (char *a, char *b) int Same = 0; // 일치횟수카운트를위한변수 int cnt = 0; // 빈도카운트를위한변수 for (int i = 0; a[i]!=0; i++) // 대상을순회하면서한원소마다 for (int j = 0; b[j]!= 0; j++) // 알고싶은문자열을순회한다. if (a[i+j] == b[j]) // 비교 Same++; // 같으면값을증가시켜서 if (Same == CountLength(b)) // 전체길이랑같으면 cnt++; // 빈도수를카운트한다.
Same = 0; return cnt; int main() char *a; char *b; cout<<"enter the word : "; cin>>a; cout<<endl<<"find : "; cin>>b; cout<<b<<" : "<<CountChar(a,b)<<endl; Solution 2 #include <iostream> using namespace std; int CountLength (char *s) // 문자열의길이를측정하는함수 int length = 0; for (char* p = s; *p!= 0; p++) // 포인터를이용해순회한다 length++; // 순회하면서값을늘리고 return length; // 그값을리턴시킨다. bool CheckSame (char *a, char *b) int cnt = 0; char *p2 = a; for (char *p = b; *p!= 0; p++) //bool값을반환하는문자열비교함수 // 일치하는문자를카운트하기위한변수 // 비교하기위한문자열의포인터복사 // 순회하면서
if (*p == *p2) // 일치하는지검사하고 cnt++; // 일치하면증가시킨다. p2++; // 비교대상도같이순회 if (cnt == CountLength(b)) // 일치한횟수와글자열의길이를비교하여 return 1; // 같으면참 return 0; // 아니면거짓 void CheckChar (char *a, char *b) int ct = 0; for (char *p1 = a; *p1!= 0 ; p1++) if (CheckSame(p1,b)) ct++; cout<<b<<" : "<<ct<<endl; // 빈도를세는함수 // 빈도카운트 // 비교대상을순회 // 몇번일치하는지검사 // 카운트를증가시킴 // 결과출력 int main() char* a; char* b; cout<<"enter the word : "; cin>>a; cout<<"find : "; cin>>b; CheckChar(a,b); return 0; // 문자열입력 // 빈도를알고싶은문자열입력
Solution 1, 2 모두같은결과임 7.10 연습문제 7.10.19 5.9.13에서정의한 Date에하루, 한달, 한해를더하는함수를작성하자, 주어진 Date를보고해당요일을내주는함수를작성하자. 마지막으로주어진 Date 이후의첫번째월요일에해당되는 Date를내주는함수를작성하자 #include <iostream> using namespace::std; struct Date int year; int month; int day; ; // 년, 월, 일을담는구조체 void PlusOne (Date * x) // 년, 월, 일에 1씩더하는함수 x->year ++; // 구조체의포인터에접근하는방법 x->month ++; x->day ++; int TotalDay (Date x) // 총날짜를계산하는함수 int sum = 0; // 총날짜의합계를담을변수 for (int i = 1; i<x.year; i++) // 년도에대한 for문 if (i%4 == 0 && i%100!= 0 i%400 ==0) // 윤년의조건
sum+=366; else sum+=365; for (int i=1; i<x.month; i++) // 달에대한 for문 if (i==1 i==3 i==5 i==7 i==8 i==10 i==12) // 마지막일이 31일인달들 sum+=31; else if (i==4 i==6 i==9 i==11) // 마지막이 30일인달들 sum+=30; else if (i==2) if (i%4 == 0 && i%100!= 0 i%400 ==0) // 윤년에는 2월이 29일 sum+=29; else // 그외에는 2월이 28일 sum+=28; sum+=x.day; // 일수는그대로더함 return sum; void Week(int sum) cout<<sum<<endl; switch (sum%7) case 1: cout<<" 월 "<<endl; // 요일을판단하는함수 // 총날짜를 7 로나눠서나머지를파악 break;
case 2: cout<<" 화 "<<endl; break; case 3: cout<<" 수 "<<endl; break; case 4: cout<<" 목 "<<endl; break; case 5: cout<<" 금 "<<endl; break; case 6: cout<<" 토 "<<endl; break; default : cout<<" 일 "<<endl; break; // 나머지에따라요일이출력됨 void NextMonday (int TotalDay, Date * x) int temp = 0; for (int i = TotalDay; i%7==1; i++) cout<<i<<endl; temp++; x->day = temp; int main() int menu = 0; Date a = 0,0,0; cout<<" 년도입력 : "; cin>>a.year; cout<<" 월입력 : "; cin>>a.month; cout<<" 일입력 : "; cin>>a.day; // 다음주월요일을파악하기위한함수 while(1) // 무한루프 cout<<endl<<a.year<<" 년 "<<a.month<<" 월 "<<a.day<<" 일 "<<endl; cout<<"------------------------------"<<endl; cout<<"1. 하루, 한달, 한해더하기 "<<endl; cout<<"2. 해당요일알아보기 "<<endl; cout<<"3. 그이후첫번째월요일로가기 "<<endl; cout<<"4. 프로그램종료하기 "<<endl; cout<<"-------------------------------"<<endl; cout<<" 원하시는동작을선택해주세요 : "; cin>>menu; switch (menu)
case 1 : PlusOne(&a); break; case 2 : Week(TotalDay(a)); break; case 3 : NextMonday(TotalDay(a),&a); break; case 4 : return 0; default : cout<<" 다시시도하시기바랍니다 "<<endl; break;