[TCPL] C++ 포인터, 배열 , 구조체 – 연습문제

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*에 대해 사용상의 어떤 제약이 있는지 조사해보자.

<TEXTAREA class=c name=code rows=10 cols=60>#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 : 역참조 할 수 없다. } </TEXTAREA>

 
 
 
 

5.9.8 여러분이 사용하고 있는 컴파일러가 포인터를 사용한 배열 순회와 색인을 사용한 배열 순회에 대해 동일한 코드를 만들어 내는지 알아보기 위해 시험 프로그램을 몇 개 실행해 보자.

<TEXTAREA class=c name=code rows=10 cols=60>#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; } </TEXTAREA>

5.9.12 어떤 string 안에 들어 있는 글자쌍의 출현 빈도를 세는 함수를 하나 만들고, char의 배열에 대해 동일하게 동작하는 함수를 하나 더 만들자.

char배열을 이용

Solution 1

<TEXTAREA class=c name=code rows=10 cols=60>#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; } </TEXTAREA>

Solution 2

<TEXTAREA class=c name=code rows=10 cols=60>#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) //bool값을 반환하는 문자열 비교 함수 { int cnt = 0; //일치하는 문자를 카운트하기 위한 변수 char *p2 = a; //비교하기 위한 문자열의 포인터 복사 for (char *p = b; *p != 0; p++) //순회하면서 { 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; } </TEXTAREA>

Solution 1, 2 모두 같은 결과임

7.10 연습 문제

7.10.19 5.9.13에서 정의한 Date에 하루, 한 달, 한 해를 더하는 함수를 작성하자, 주어진 Date를 보고 해당 요일을 내주는 함수를 작성하자. 마지막으로 주어진 Date 이후의 첫 번째 월요일에 해당되는 Date를 내주는 함수를 작성하자


<TEXTAREA class=c name=code cols=60 rows?10?>#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) //총 날짜를 7로 나눠서 나머지를 파악 { case 1: cout<<“월”<<endl; 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; } } } </TEXTAREA>

    

  jk37.pdf

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 

This site uses Akismet to reduce spam. Learn how your comment data is processed.