'소프트웨어'에 해당되는 글 190건

  1. 2007.02.28 [2004년 중간 10번] 생년월일 이름 출력 - 매개변수 / 나머지
  2. 2007.02.28 [2004년 중간 9번] 10 ~ 20까지 출력 - 단순 출력 / 재귀호출
  3. 2007.02.28 [2004년 중간 8번] 약수 출력 - 조건 반복문
  4. 2007.02.27 [2004년 중간 7번] 난수 발생 - rand()
  5. 2007.02.27 [2004년 중간 6번] 사칙 연산 - 명령줄 인수 / 함수 호출
  6. 2007.02.26 [2004년 중간 5번] 최대 / 최소값 - 포인터 / 삼항 연산자
  7. 2007.02.26 [2004년 중간 4번] 문자열 변환 - ASCII 코드
  8. 2007.02.26 [2004년 중간 3번] 구간 합 - for 반복문
  9. 2007.02.25 [2004년 중간 2번] 문자열 입력 / 출력 - 단항 연산자
  10. 2007.02.25 [2004년 중간 1번] 키보드 문자열 입력 및 모음 출력 - switch-case 문
  11. 2007.02.25 [2003년 중간] 정리
  12. 2007.02.25 [2003년 중간 10번] 강제 대입 (Brute force) 이해 - 재귀호출
  13. 2007.02.25 [2003년 중간 9번] 누적합(cumulative) / 누적곱(factorial) - 재귀 호출(recursive call)
  14. 2007.02.25 [2003년 중간 8번] 역순 출력 - 문자열 다루기
  15. 2007.02.25 [2003년 중간 7번] 사칙 연산 - 매개변수
  16. 2007.02.25 [2003년 중간 6번] 문자열 조작 출력 - 문자열 병합 / 대소문자 변환
  17. 2007.02.25 [2003년 중간 5번] 성적 처리 - 조건문
  18. 2007.02.25 [2003년 중간 4번] 소수 / 약수 - 반복문
  19. 2007.02.25 [2003년 중간 3번] 소수 출력 - 조건 / 반복문
  20. 2007.02.25 [2003년 중간 2번] 8진수 16진수 변환 - 스트림에서 플래그 값 / 8 / 16 진수
  21. 2007.02.25 [2003년 중간 1번] 제곱근 - 배열 / 제곱근 / 절대값
  22. 2007.02.24 [2003년 기말] 정리
  23. 2007.02.24 [2003년 기말 12번] 반올림 값 출력 - 형변환
  24. 2007.02.24 [2003년 기말 11번] 합 출력 - 재귀호출
  25. 2007.02.24 [2003년 기말 10번] 주민등록번호 앞자리 - 나눗셈 / 끊어 읽기
  26. 2007.02.24 [2003년 기말 9번] 최대값 / 최소값 - 삼항 연산자
  27. 2007.02.24 [2003년 기말 8번] 정수 / 실수 계산 - 캐스트 연산자 / 형변환 / 오버로딩
  28. 2007.02.24 [2003년 기말 7번] 키보드 문자열 조작 - 동적 할당 / 대소문자 변형 / 문자열 병합
  29. 2007.02.24 [2003년 기말 6번] 육면체 부피 계산 - 클래스 / 생성자 / friend
  30. 2007.02.24 [2003년 기말 5번] 최소공배수 / 최대공약수 - 나머지 / 반복문




목적
  - 매개변수 입력을 익힌다. 원하는 자릿수의 숫자를 출력을 한다.

문제

사용자 삽입 이미지

코드

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])

{
 float iYear, iMonth, iDay;
 iYear = iMonth = iDay = 0;


 if(argc < 3)
 {
  cerr << "ERROR : 인수 부족" << endl;
  return -1;

 }

 if(argc > 3)
 {
  cerr << "ERROR : 인수 초과" << endl;
  return -1;

 }

 iYear = int(atof(argv[1]) / 10000) > 50 ? 1900 + int(atof(argv[1]) / 10000) : 2000 + int(atof(argv[1]) / 10000);
 iMonth = (int)atof(argv[1]) % 10000 / 100;
 iDay = (int)atof(argv[1]) % 100;

 cout << argv[2] << "님의 생일은 " << iYear << "년 " << iMonth << "월 " << iDay << "일 입니다." << endl;

 return 0;


}



해설
  - 명령줄 매개변수 입력은 예전 문제들 많으니깐 참조 하시기 바랍니다.

참고
  - 유사 문제
  - http://www.winapi.co.kr/clec/cpp1/10-4-2.htm : main 함수의 인수

Posted by 카켈



목적
  - 재귀 호출을 익힌다.

문제

사용자 삽입 이미지

코드
#include <iostream>

using namespace std;

void v_Printfact(int);

void v_Printfact(int iIn)
{
 if(iIn > 20)
 {}

 else
 {
  cout << iIn << " ";
  v_Printfact(iIn + 1);

 }
 
 return;
}


int main(void)
{
 int iIn = 10;
 v_Printfact(iIn);
 cout << '\n';

 return 0;
}

해설
  - 20까지 숫자를 출력 1을 더한 인수를 넣어 다시 실행, 그 이상은 리턴하여 실행하지 않습니다.

참고
  - 유사 문제

Posted by 카켈






목적
  - 약수를 출력한다.

문제
사용자 삽입 이미지

코드

#include <iostream>

using namespace std;

int main(void)
{
 long lIn = 0;
 int i = 1;

 while(lIn < 101)
 {
  cout << "100보다 큰 정수를 입력하세요 : ";
  cin >> lIn;

 }

 while(i <= lIn)
 {
if(lIn % i == 0)
   cout << i << " ";

  i++;
 }

 cout << endl;

 return 0;
}



해설
  - lIn 이 100 이하면 다시 작동하는 알고리듬을 썼으며 약수는 나머지가 0인 부분만 활용했습니다.

참고
  - 유사 문제


Posted by 카켈




목적
  - 특정 범위의 난수를 만들줄 안다.

문제

사용자 삽입 이미지


코드
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(void)
{
 srand((unsigned)time(NULL));
 rand();

 double afRand[30] = {0.0};
 double dTotal = 0.0;
 int i = 0;
 

 cout << "생성된 난수 : " << endl;
 while (i < 30)
 {
  afRand[i] = ((rand() % 2000) - 1000) / 1000.0;
  cout << afRand[i] << '\t';
  dTotal += (afRand[i] * afRand[i]);

  i++;
 }

 cout << endl << "난수의 제곱 합 : " << dTotal << endl;

 return 0;
}
해설
  - 원하는 범위의 난수를 만드는 방법은 (rand() % 원하는 값의 0 을 기준으로 최대값 - +- 중간값) / 자릿수의 역수
  - 마지막에 1000.0 으로 하지 않으면 int 형 나눗셈이 되어 버려서 int 형으로 전환 소숫점이 삭제되어 0이 출력됩니다.

참고
  - 유사 문제

Posted by 카켈




목적
  - 프로그램 인수를 활용한다.
  - 함수 호출을 이해한다.

문제
사용자 삽입 이미지

코드

#include <iostream>
#include <cstdlib>
#include <cstring>

float add(float aA, float aB)
{ return aA + aB; }

float min(float aA, float aB)
{ return aA - aB; }

float mul(float aA, float aB)
{ return aA * aB; }

float div(double aA, double aB)
{ return aA / aB; }

using namespace std;

int main(int argc, char* argv[])
{
 if(argc < 4 || argc > 4)
 {
  cerr << "ERROR : 인수 부족" << endl;
  return 0;

 }

  if ( !(strcmp(argv[1], "+")) )
  {
   cout << argv[2] << " " << argv[1] << " " << argv[3] << " = " << add( atof(argv[2]), atof(argv[3]) ) << endl; }
 
  else
   {
   
   if ( !(strcmp("-", argv[1])) )
    { cout << argv[2] << " " << argv[1] << " " << argv[3] << " = " << min( atof(argv[2]), atof(argv[3]) ) << endl; }
   
   else
   {
    if ( !(strcmp("*", argv[1])) )
     { cout << argv[2] << " " << argv[1] << " " << argv[3] << " = " << mul( atof(argv[2]), atof(argv[3]) ) << endl; }

    else
    {
     if ( !(strcmp("/",argv[1])) )
      { cout << argv[2] << " " << argv[1] << " " << argv[3] << " = " << div( atof(argv[2]), atof(argv[3]) ) << endl; }

     else
     {
      cerr << "잘못된 연산자 입니다." << endl;

     }

    }

   }

  }
 
 return 0;
}


해설
  - argv 문자열 변수는 if(argv[1] == "+") 이런식으로 문자열 비교를 할수 없었습니다. strcmp 함수를 받아 NOT 연산자를 통해 비교 하시면 됩니다.
  - 커맨드 라인(실행줄) 파라매터(인수)는 이전 문제에 많이 언급되어 있습니다. 검색 하여 보시기 바랍니다.
  - cerr 객체는 cout 과 유사한 역할을 하나 오류 메시지를 출력하는 목적으로 만들어 졌습니다.

참고
  - 유사 문제
  - 실행 화면

사용자 삽입 이미지

Posted by 카켈




목적
  - 포인터를 이해한다.
  - 삼항 연산자를 자유롭게 쓴다.

문제

사용자 삽입 이미지
코드

#include <iostream>

using namespace std;

int main(void)
{
 float afIn[4] = {0};
 int i = 0;
 float *fMax,*fMin;
 fMax = fMin = &afIn[0];

 cout << "네 개의 실수를 입력하세요 : ";
 while(i < 4)
 {
  cin >> afIn[i];
  fMax = (*fMax < afIn[i] ? &afIn[i] : fMax);
  fMin = (*fMin > afIn[i] ? &afIn[i] : fMin);
  i++;
 
 }

 
 cout << "최소값 : " << *fMin << endl << "최대값 : " << *fMax << endl;

 return 0;
}


해설
  - 포인터로 *[변수] 선언시 [변수] 는 그 값이 저장될 주소(reference)를 가리키며 *[변수]를 하면 그 저장된 주소로 가면 가지고 있는 값을 가리킵니다.(derefernce)
  - 포인터 아닌 일반 변수가 포인터에서 쓰는 주소를 저장하고 싶으면 앞에 & (reference) 연산자를 붙이면 됩니다. C++ 에서 새로 추가된 기능 중 하나 입니다.
  - 삼항 연산자는 많이 풀어 봐서 이해 되실 겁니다. 유사 예제들을 검색해서 보시기 바랍니다.

참고
  -유사문제

Posted by 카켈




목적
  - ctype.h 를 쓰지 않고 문자의 속성을 구분하고 변경할줄 안다.
  - ASCII 코드표를 이해한다.

문제

사용자 삽입 이미지
코드

#include <iostream>

using namespace std;

int main(void)

{
 char sIn[255] = {0};
 char sOut[255] = {0};
 int i, j;
 i = j = 0;

 cout << "문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');

 while(sIn[i] != 0)
 {
  if(sIn[i] >= 65 && sIn[i] <= 90)
  {
   sOut[j] = sIn[i] + 32;
   j++;
  }

  else
  {

   if(sIn[i] >= 97 && sIn[i] <=122)
   {
    sOut[j] = sIn[i] - 32;
    j++;
   }

   else
   {
    sOut[j] = sIn[i];
    j++;
   }

  }

  i++;
 }


 cout << "변환된 문자열 : " << sOut << endl;
 i = j = 0;

 cout << "공백문자 제거 : ";

 while(sOut[i] != 0)
 {
  if(sOut[i] == ' ');
  else
   cout << sOut[i];

  i++;
 }

 cout << endl;

 return 0;
}


해설
  - ASCII 코드를 이해한다면 ctype.h 의 tolower() 나 toupper() isspace() 함수를 간단하게 구현할수 있습니다.

참고
  -유사문제

Posted by 카켈




목적
  - 특정 구간간의 덧셈을 구한다.

문제

사용자 삽입 이미지
코드

#include <iostream>

using namespace std;

int main(void)
{
 int iA, iB, iTemp, iTotal;
 iA = iB = iTemp = iTotal = 0;

 cout << "정수 두개를 입력하세요 : ";
 cin >> iA >> iB;

 if(iA > iB)
 {
  iTemp = iA;
  iA = iB;
  iB = iTemp;

 }

 cout << iA << " 부터 " << iB << "까지의 합 : ";

 for(iTemp = iA; iTemp <= iB; iTemp++)
  iTotal += iTemp;

 cout << iTotal << endl;

 return 0;
}


해설
  - iSwap 문으로 큰수 작은수를 iA , iB로 나눈후 간단하게 for 문으로 덧셈을 구했습니다.

참고
  - 유사문제

Posted by 카켈




목적
  - 단항 연산자에 대해 연습한다.
  - 문자열을 입력 및 조합한 후 출력한다.

문제
사용자 삽입 이미지
코드

#include <iostream>

using namespace std;

int main(void)
{
 char sIn_a[255] = {0};
 char sIn_b[255] = {0};
 int i, j;
 i = j = 0;

 cout << "첫번째 문자열 입력 : ";
 cin.getline(sIn_a,255,'\n');
 cout << "두번째 문자열 입력 : ";
 cin.getline(sIn_b,255,'\n');

 cout << "첫번째 문자열 : ";
 while(sIn_a[i] != 0)
 {
  cout << sIn_a[i];
  i++;

 }

 cout << endl;

 cout << "두번째 문자열 : ";
 while(sIn_b[j] != 0)
 {
  cout << sIn_a[j];
  j++;

 }

 cout << endl;

 cout << "병합된 문자열 : ";
 cout << sIn_a[i] << sIn_b[j] << endl;

 cout << "뒤집힌 문자열 : ";
 
 while(j-- > 0)
   cout << sIn_b[j];

 while(i-- > 0)
   cout << sIn_a[i];
 
 cout << endl;

 return 0;

}


해설
  - 이전 문제들에도 문자열 병합과 출력이 있어서 약간의 변형을 했습니다. cstring / string.h 를 쓰지 않고 병합 출력을 하였습니다.

단항 연산자(unary operator)는 피연산자가 하나면 되는 연산자 입니다. 피연산자는 변수여야 하며(그 자체로는 변하지 않는 l-value) 앞에 붙었느냐 아니면 뒤에 붙었느냐에 따라 달라 집니다.
[피연산자]++ => 쓰는 라인에서는 증가가 없지만 다음 줄에서는 [피연산자]가 1 증가 합니다.
[피연산자]-- => 쓰는 라인에서는 증가가 없지만 다음 줄에서는 [피연산자]가 1 감소 합니다.
++[피연산자] 쓰는 라인에서는 증가가 되며 그 줄 부터 [피연산자]가 1 증가 합니다.
--[피연산자] 쓰는 라인에서는 감소가 되며 그 줄 부터 [피연산자]가 1 감소 합니다.

자세한 사항은 키로그를 참조 하시기 바람니다.

참고
  - 유사 문제
  - http://www.winapi.co.kr/clec/cpp3/28-3-2.htm : 증감 연산자



Posted by 카켈




목적
  - 문자열에서 특정 문자를 추려서 계산한다.
문제

사용자 삽입 이미지

코드

#include <iostream>
#include <ctype.h>

using namespace std;


int main(void)
{
 char sIn[255] = {0};
 int iCount, iMo, iSpace;
 iCount = iMo = iSpace = 0;
 cout << "문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');

 while(sIn[iCount] != 0)
 {
  switch(tolower(sIn[iCount]))
  {
   case 'a':
    iMo++;
    break;

   case 'e':
    iMo++;

    break;
   case 'i':
    iMo++;
    break;
   
   case 'o':
    iMo++;
    break;

   case 'u':
    iMo++;
    break;

   case ' ':
    iSpace++;
    break;

   default:
    break;

  }

  iCount++;
 }

  cout << "문자의 수 : " << iCount << endl;
  cout << "모음의 수 : " << iMo << endl;
  cout << "공백의 수 : " << iSpace << endl;

 return 0;

}


해설
  - 모음에는대소문자를 가리지 않으므로 소문자로 일괄처리하여 속도를 빠르게(?) 했습니다.
  - 공백은 ' ' 로 처리하면 됩니다.
  - switch-case 문은 이전 문제에서 많이 다루었기 때문에 특별히 언급하지 않겠습니다. 키로그를 참조하시기 바랍니다.

참고
  - 유사 문제



Posted by 카켈



 
2003년 C++ 중간 고사 실습 문제 입니다. 기말을 먼저 풀어서 그런지 그렇게 어렵진 않았습니다.
 
  저작권 공지
  문제/해답 : http://signal.korea.ac.kr/~ychlee
  코드 : http://cakel.tistory.com
  교육용을 목적으로 자유롭게 쓰실수 있습니다.

Posted by 카켈




목적
  - 강제 대입을 재귀 호출에 응용시켜 본다.

문제

사용자 삽입 이미지
코드

#include <iostream>
#include <cmath>

using namespace std;

void do_5_equation(int aIn)
{
 if(pow(aIn, 5) - 5 * pow(aIn, 4) - 15 * pow(aIn, 3) + 85 * pow(aIn, 2) - 26 * aIn - 120 == 0)
  cout << aIn << " ";

 if(aIn > 10) return;
 do_5_equation(aIn + 1);
 return;

}

int main(void)
{
 cout << "주어진 오차방정식의 근 : ";
 do_5_equation(-10);
 cout << endl;

 return 0;
}


해설
  -  재귀호출시 중요한 점은 return 시 호출시의 다음 문장으로 돌아 간다는 것입니다.
  -  따라서 -10 -9 -8 ... 8 9 10
                           9
                         8
                       7
                   ...
               -9
           -10

    형태로 aIn 값이 변합니다.
    이는 스택(통)형으로 수행후 돌아갈 다음 문장 주소를 쌓아 놓았기 때문입니다.

참고
  - 재귀 호출 유사 문제
  - 유사 문제

Posted by 카켈



목적
  - 재귀 호출을 실제 수학에 응용한다.

문제

사용자 삽입 이미지
코드

#include <iostream>

using namespace std;

long l_Cumulative(unsigned int uiIn)
{ return uiIn + ( uiIn > 0 ? l_Cumulative(uiIn - 1) : 0); }

double l_Factorial(unsigned int uiIn)
{ return uiIn * ( uiIn > 2 ? l_Factorial(uiIn - 1) : 1); }


int main(void)
{
 unsigned int uiIn;
 cout << "양의 정수 값을 입력하세요 : ";
 cin >> uiIn;

 cout << "1부터 " << uiIn << " 까지의 누적합 : " << l_Cumulative(uiIn) << endl ;
 cout << "1부터 " << uiIn << " 까지의 누적곱 : " << l_Factorial(uiIn) << endl ;

 return 0;
}


해설
  - 삼항 연산자로 판정을 간단하게 해서 누적 합/ 곱을 출력했습니다.
  - 누적 곱(factorial) 인 경우 값이 엄청 크기 때문에 double 형으로 했습니다. 그래도 안되는 경우가 많기 때문에 더 큰 수를 받아 들이는 알고리듬이 따로 존재 합니다.

참고
  - 재귀 호출 관련 문제

Posted by 카켈




목적
  - 문자열을 다룬다.
문제
사용자 삽입 이미지

코드

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
 char sIn[255] = {0};
 int i = 0;

 cout << "문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');
 i = strlen(sIn);

 while(i >= 0)
 {
  cout << sIn[i - 1];
  i--;
 }

 cout << endl;

 return 0;
}


해설
  - cin 의 getline 매소드 (맴버함수) 는 문자열을 받아 들이는 함수입니다.

참고
  - 유사 문제

Posted by 카켈




목적
  - 매개변수를 입력 받아 함수를 이용하여 출력한다.

문제
사용자 삽입 이미지

코드

#include <iostream>
#include <cstdlib>

using namespace std;

void add(float aA, float aB)
{
 cout << aA << " + " << aB << " = " << aA + aB << endl;
 return;
}

void sub(float aA, float aB)
{
 cout << aA << " - " << aB << " = " << aA - aB << endl;
 return;
}

void mul(float aA, float aB)
{
 cout << aA << " * " << aB << " = " << aA * aB << endl;
 return;
}

void div(float aA, float aB)
{
 cout << aA << " / " << aB << " = " << aA / aB << endl;
 return;
}

int main(int argc, char* argv[])
{
 if(argc != 3) cout << "두 개의 인수를 넣어 주세요." << endl;
 else
 {
  add(atof(argv[1]), atof(argv[2]));
  sub(atof(argv[1]), atof(argv[2]));
  mul(atof(argv[1]), atof(argv[2]));
  div((float)atof(argv[1]), (float)atof(argv[2]));

 }


 return 0;
}


해설
  - 유사 문제가 많아서 크게 설명하지 않겠습니다. div 함수를 그냥 하니깐 오류가 났습니다. cstdlib 의 div(int, int) 함수와 overloaded 모호 충돌 오류가 났습니다. 강제로 float 형변환을 해서 문제를 해결 했습니다.

참고
  -유사 문제
Posted by 카켈




목적
  - 문자열을 조작할 줄 안다.

문제
사용자 삽입 이미지

코드

#include <iostream>
#include <cstring>
#include <ctype.h>

using namespace std;

int main(void)
{
 char sIn[255] = {0};
 char *spA, *spB, *spC;
 spA = spB = spC = NULL;

 cout << "첫번째 문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');

 spA = new char[strlen(sIn) + 1];
 strcpy(spA, sIn);

 cout << "두번째 문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');

 spB = new char[strlen(sIn) + 1];
 strcpy(spB, sIn);

 spC = new char[strlen(sIn) + strlen(sIn) + 1];
 strcpy(spC, spA);
 strcat(spC, spB);

 cout << "첫번재 문자열 : " << spA << endl << "두번째 문자열 : " << spB << endl;
 cout << "병합된 문자열 : " << spC << endl;
 cout << "변환후 문자열 : ";

 for(int i = 0; i < strlen(spC); i++)
 {
  if(islower(spC[i])) cout << (char)toupper(spC[i]);
  else cout << (char)tolower(spC[i]);

 }
 
 cout << endl;

 spA = spB = spC = NULL;
 delete spA, spB, spC;

 return 0;
}

해설
  - tolower 나 toupper 의 리턴형은 int 이므로 강제 형변환(캐스트) 했습니다.
  - 동적 할당으로 sIn 문자열을 용량을 할당받은 공간에 포인터로 받아 저장했습니다.
  - 동적 할당을 받았으면 반환 하는 걸 잊지 말아야 합니다.

참고
  - 유사 문제

Posted by 카켈




목적
  - 원하는 값을 원하는 조건에 맞게 출력하고 반복 수행한다.

문제

사용자 삽입 이미지

코드

#include <iostream>

using namespace std;

int main(void)
{
 float aIn = 1.0;
 do
 {
  cout << "성적을 입력하세요 : ";
  cin >> aIn;

  if(aIn != 0)
  {
   if(aIn >= 90) cout << "합격입니다. 축하드립니다." << endl;
   if(aIn >= 80 && aIn < 90 ) cout << "예비합격입니다." << endl;
   if(aIn >= 60 && aIn < 80 ) cout << "재시험을 보십시오." << endl;
   if(aIn < 80 ) cout << "불합격 입니다." << endl;
   cout << endl;
  }


 } while(aIn != 0);

 return 0;

}


해설
  - 변칙적인 문장인 break 구문을 일부러 없앴습니다.
  - if 조건문으로 숫자 판정을 받습니다.

참고
  - 유사 문제
 


Posted by 카켈




목적
  - 소수와 약수를 출력한다.

문제
사용자 삽입 이미지

코드

#include <iostream>

using namespace std;

bool isPrime(int aIn)
{
 int i = 2;
 while(i < aIn)
 {
  if(aIn % i == 0) return false;
  i++;
 }

 return true;
}

int main(void)
{
 int i, iIn;
 i = iIn = 0;
 
 while( !(iIn > 100 && iIn < 200) )
 {
  cout << "100 ~ 200 사이의 정수값을 입력하세요 : ";
  cin >> iIn;

 }

 if(isPrime(iIn))
 {
  cout << "입력한 정수 " << iIn << " 는 소수 입니다.";
 }

 else
 {
  i = 1;
  cout << "입력한 정수 " << iIn << " 는 다음과 같은 약수를  가지고 있습니다." << endl;
  while(i < iIn)
  {
   if(iIn % i == 0) cout << i << " ";
   i++;
  }


 }

 cout << endl;

 return 0;
}


해설
  - 이전 문제와 다른 알고리듬으로 소수를 출력했습니다.
  - iostream 에서는 C 와 달리 bool 형 변수(false / true) 가 존재 합니다.

참고
  - 유사 문제

Posted by 카켈



목적
  - 소수 출력과 합을 구할줄 안다.

문제
사용자 삽입 이미지

코드

#include <iostream>

using namespace std;

int main(void)
{
 int iStart = 50;
 const int iEnd = 100;
 int iPrime, iTotal;
 int i = 2;
 iPrime = iTotal = 0;
 
 cout << "50 과 100사이에 존재하는 소수들 : ";

 while(iStart <= iEnd)
 {
  while(i < iStart)
  {
   if ( iStart % i == 0 )
   {
    iPrime = 0;
    i++;
    break;
   }

   else
   {
    iPrime = 1;
    i++;

   }

  }

  if(iPrime == 1)
  {
   cout << iStart << " ";
   iTotal += iStart;

  }

  iPrime = 0;
  i = 2;
  iStart++;

 }

 cout << endl << "50 과 100사이에 존재하는 소수들의 합 : " << iTotal << endl;

 return 0;
}


해설
  - 여러가지 알고리듬으로 풀수 있습니다. 재귀 호출을 시도하여 출력할려 했으나 실패하여 단순한 반복 알고리듬으로 대체 되었습니다. 이전 문제들을 보시고 쓸만한 소수 알고리듬을 익혀 주시기 바랍니다.

참고
  - 유사 문제


Posted by 카켈




목적
  - iostream 에서 16진수 8진수 출력을 익힌다.

문제
사용자 삽입 이미지

코드

#include <iostream>

using namespace std;

int main(void)
{
 int iIn = 0;
 cout << " 양의 정수를 하나 입력하세요 : ";
 cin >> iIn;
 cout << "10진 표현 : " << iIn << endl;
 cout << " 8진 표현 : 0" << oct << iIn << endl;
 cout << "16진 표현 : 0x" << hex << iIn << endl;

 return 0;
}


해설
  - 스트림에 dec/oct/hex 연산자(플래그 : flag)를 삽입(cin : <<)/추출(cout : >>) 하면 해당 숫자 자료형이 8진수/16진수가 됩니다.
  - 0/0x 는 8진수/16진수 구별하기 위해서 만든 접두어 입니다.

참고
  - http://user.chollian.net/~relay/main_soft/document/c_c++.htm : iomanip.h 부분에 있습니다.



Posted by 카켈




목적
  - 수학함수를 이용할줄 안다.
문제
사용자 삽입 이미지
코드

#include <iostream>
#include <cmath>

using namespace std;

int main(void)
{
 float faIn[3] = {0};
 float fTotal = 0.0;
 int i = 0;
 cout << "실수값 세 개를 입력하세요 : ";
 cin >> faIn[0] >> faIn[1] >> faIn[2];
 
 while(i<3)
 {
  cout << "│" << faIn[i] << "│ 의 제곱근 : " << sqrt(faIn[i] >= 0 ? faIn[i] : -1 * faIn[i] )<< endl;
  fTotal += sqrt(faIn[i] >= 0 ? faIn[i] : -1 * faIn[i] );
  i++;
 }

 cout << endl << "제곱근들의 합 : " << fTotal << endl;

 return 0;
}


해설
  - 절대값을 단순하게 조건문으로 구현했습니다.

if(faIn[i] >=)
 { faIn[i] = faIn[i]; }
  else { faIn[i] = - faIn[i]; }

  - 이 방식 말고 정수형은 abs(faIn[i]) 실수는 fabs(faIn[i])) 쓰면 됩니다. 정수형 abs 함수를 실수 인수에다 넣으면 소숫점이 잘려 나가므로 엉뚱한 결과가 나옵니다.

  - '│' 문자는 'ㅂ' 을 치고 난뒤에 바로 한자를 누르면 선택 창이 나옵니다.

참고
  - math.h / cmath 함수를 쓴 문제

Posted by 카켈




  2003년 C++ 실기 기말고사입니다. 중간 부터 할려고 했었는데 실수로 2문제를 먼저 풀어서 그냥 풀자는 의미에서 기말을 다 풀었습니다.  iostream/cout/cin 같은 C++ 만의 고유한 부분을 최대한 쓸려고 노력했습니다. 클래스 부분은 여기서 간단하게 보고 넘어 가기엔 중요도가 크기 때문에 따로 공부 하시기 바랍니다. C++ 기초를 너머 객체지향프로그래밍을 공부하시는데 도움이 되시기 바랍니다.

  저작권 표기
  문제/해답 : http://signal.korea.ac.kr/~ychlee
  코드 : http://cakel.tistory.com
  교육용을 목적으로 자유롭게 사용이 가능합니다.

Posted by 카켈



목적
  - 반올림을 C에 적용 시키고 이해한다.

문제

사용자 삽입 이미지

풀이

#include <iostream>

using namespace std;

int main(void)
{
 float fIn = 0;

 while(1)
 {
  cout << "실수값 하나를 입력하세요 : ";
  cin >> fIn;
 
  if(fIn == 0) break;
  cout << fIn << " 의 반올림한 값은 " <<
   ((fIn - (int)fIn) >= 0.5 ? (int)fIn + 1 : (int)fIn) << " 입니다." << endl << endl;

 
 }

 return 0;
}

해설
  - 실수형 자료를 정수형 변환(캐스팅)을 하면 소숫점이 지워 집니다. 이를 이용하여 차를 구해 0.5 이상이면 정수형 변환한 값에다가 1을 더한 값을 아니면 변환된 값만 출력합니다.
 - while 문으로 무한 반복을 수행하다가 0 이 입력되면 break 로 탈출하여 종료 합니다.

참고
  - 유사 문제 : 형변환 활용

Posted by 카켈



목적
  - 재귀 호출(Recursive call)을 익힌다.
문제
사용자 삽입 이미지
풀이

#include <iostream>

using namespace std;

long l_Recursive(long aIn)
{ return aIn + (aIn < 456 ? l_Recursive(aIn + 1) : 0); }

int main(void)
{ cout << "123부터 456 까지의 합 : " << l_Recursive(123) << endl; return 0; }

해설
  - 재귀 호출은 그 원리를 이해하면 정말 효율적인 코딩이 가능합니다.
  - 자기 자신을 계속 호출하되 리턴 값이 계속 누적 되기 때문에 무한 반복에서 빠져 나갈수 있는 조건만 갖추면 원하는 범위 내에서 계속 연산을 할수 있습니다.

  - 이 경우 455 전 까지만 계속 다음 숫자를 호출 합니다. 123 에서 시작하라고 하니 결국은

123 + l_Resursive(124)
123 + 124 + l_Resursive(125)
... (계속 반복)
123 + 124 + 125 + 126 + ... l_Resursive(454)
123 + 124 + 125 + 126 + ... 455 + l_Resursive(455)
123 + 124 + 125 + 126 + ... 456 + 0

이렇게 되어 원하는 값인 123 + 124 + ... + 455 + 456 = 96693 이렇게 됩니다.

  - 스택 방식으로 되어 있기 때문에 시스템 프로그래밍 공부 하시는 분들에게 유익한 함수 입니다. 나중에 어셈블러 공부 하실일 있으면 미리 익혀 두시면 참 도움이 될 겁니다.

참고

  - http://www.winapi.co.kr/clec/cpp2/16-2-1.htm : 재귀호출


Posted by 카켈



목적
  - 원하는 단위로 나누어 쓸줄 안다.

문제

사용자 삽입 이미지

풀이

#include <iostream>

using namespace std;

int main(void)
{
 long lIn;

 cout << "주민등록번호 처음 6자리를 입력하세요 : ";
 cin >> lIn;
 cout << "당신은 " << (lIn / 10000 < 40 ? 2000 + lIn / 10000 : 1900 + lIn / 10000) << "년 "
  << (lIn % 10000) / 100 << "월 "
  << (lIn % 100) << "일에 태어나셨습니다." << endl;

 return 0;

}


해설
 - 초를 입력 받아서 일 / 시 / 분 / 초로 나누는 문제와 유사한 풀이법입니다.
참고
  - 유사 문제

Posted by 카켈




목적
  - 키보드로 실수 값을 배열로 받을 줄 안다.
  - 최대 / 최소값을 찾아 낸다.
  - 삼항 연산자를 쓸 줄 안다.

문제
사용자 삽입 이미지
풀이

#include <iostream>

using namespace std;

int main(void)
{
 float fIn[5] = {0};
 float fMin, fMax;
 int i = 0;
 cout << "다섯개의 실수 값을 입력하세요 : ";
 cin >> fIn[0] >> fIn[1] >> fIn[2] >> fIn[3] >> fIn[4];
 
 fMax = fMin = fIn[0];

 while(i < 5)
 {
  fMax = fMax < fIn[i] ? fIn[i] : fMax;
  fMin = fMin > fIn[i] ? fIn[i] : fMin;
  i++;
 }

 cout << "최소값 : " << fMin << endl << "최대값 : " << fMax << endl;

 return 0;
}

해설
  - C 에서 주욱 보셨으면 크게 어려울 문제는 없습니다.
  - 삼항 연산자는 [조건] ? [참일때] : [거짓일때] 로 위 조건문에 값으로 바꿔지는 간단한 조건식입니다.

참고
  - 유사 문제

Posted by 카켈



목적
  - 강제 형변환에 대해 정확한 이해를 가진다.
  - 오버로딩 함수를 작성한다.

문제
사용자 삽입 이미지

풀이

#include <iostream>

using namespace std;

 void add(double aA, double aB)
 {
  cout << "add(double, double) 함수가 호출되었습니다." << endl;
  cout << aA << " + " << aB << " = " << aA + aA << endl;
 
  return;
 }

 void add(int aA, int aB)
 {
  cout << "add(int, int) 함수가 호출되었습니다." << endl;
  cout << aA << " + " << aB << " = " << aA + aB << endl;
 
  return;
 }

int main(void)
{
 double dA, dB;
 dA = dB = 0;

 cout << "두 실수를 입력하세요 : ";
 cin >> dA >> dB;
 cout << endl;

 if((int)dA == dA && (int)dB == dB) add((int)dA, (int)dB);
 else add(dA, dB);

 

 return 0;
}

해설
  - 오버로딩 함수는 형식(프로토타입)에 따라 같은 함수명이라도 서로 다른 인수와 다른 출력을 가질수 있게 만들어진 함수 형식입니다. 여러 제약을 완화 하는데 많은 도움을 줍니다.

  - double(배정도 소숫점) 형식에서 int(정수형) 형식으로 강제 형변환(캐스팅)을 하면 소숫점이 떨어져 나가기 때문에 형변환 하기 전과 후의 값 상태를 봐서 함수의 인수를 int 형으로 할 것인지 아니면 double 형으로 할것인지 정하면 됩니다.

참고
  - http://www.winapi.co.kr/clec/cpp1/5-3-4.htm : 캐스트(cast, 형변환) 연산자
  - http://tea815.com.ne.kr/cpp/604.htm : 오버로딩(overloading)

Posted by 카켈





목적
- 문자열을 병합한다.
- 대소문자를 변형 시킨다.
- 동적할당에 대해 이해한다.
- 키보드로 문자열을 받아 출력한다.

문제

사용자 삽입 이미지
풀이

#include <iostream>
#include <cstring>
#include <ctype.h>

using namespace std;

int main(void)
{
 char sIn[255] = {0};
 int iCount = 0;
 char *cpA, *cpB, *cpC;
 cpA = cpB = cpC = NULL;

 cout << "첫번째 문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');
 cpA = new char[strlen(sIn) + 1];
 strcpy(cpA, sIn);

 cout << "두번째 문자열을 입력하세요 : ";
 cin.getline(sIn,255,'\n');
 cpB = new char[strlen(sIn) + 1];
 strcpy(cpB, sIn);

 cpC = new char[strlen(cpA) + strlen(cpB) + 1];
 strcpy(cpC, cpA);
 strcat(cpC, cpB);

 cout << "병합된 문자열 : " << cpC << endl;
 cout << "대소문자 변환후 문자열 : ";

 for(iCount = 0; iCount < strlen(cpC); iCount++)
 {
  if(islower(cpC[iCount])) cout << (char)(toupper(cpC[iCount]));
  else cout << (char)tolower(cpC[iCount]);

 }

 cout << endl;

 cout << "순서 뒤바뀐 문자열 : ";
 for(iCount = strlen(cpC) - 1; iCount >= 0; iCount--)
 {
  if(islower(cpC[iCount])) cout << (char)(toupper(cpC[iCount]));
  else cout << (char)tolower(cpC[iCount]);

 }

 cout << endl;

 return 0;
}


해설
  - 메모리를 동적으로 받아 넣기 위해서 문자열 포인터를 썼습니다.
  - new 명령어를 통해 새로운 공간을 받아 넣습니다. 그 크기는 입력 변수에 받은 길이 + 1 [NULL 문자] 입니다.
  - strcat 나 strcpy 에서는 NULL 문자를 붙여 넣거나 복사를 시도하면 연산 오류가 생깁니다.
  - cout 에서는 형에서 비교적 자유롭게 출력이 가능하므로 int 형으로 리턴이 되는 tolower 나 toupper 를 정수로 나오지 않게 하기 위해 char 형으로 강제 형변환 시켰습니다.

참고
  - 구글 검색 : 동적 할당
  - 유사 문제

Posted by 카켈




목적
  - 클래스를 이해하고 외부 함수에서 클래스가 보호하고 있는 변수를 이용할 줄 안다.
  - 생성자를 이해한다.

문제

사용자 삽입 이미지

풀이

#include <iostream>

using namespace std;

 class cHexahedron
 {
  public:
   friend int i_Volumn(int, int, int);
   cHexahedron() { iX = iY = iZ = 0; }
   void v_GetValue();
   void v_Print();

  private:
   int iX, iY, iZ;

 };

void cHexahedron::v_GetValue()
{
 int aX, aY, aZ;
 aX = aY = aZ = 0;
 cout << "육면체의 가로, 세로, 높이를 입력하세요 : ";
 cin >> aX >> aY >> aZ;
 iX = aX; iY = aY; iZ = aZ;
 
 return;
 
}

void cHexahedron::v_Print()
{
 cout << "육면체의 부피 : " << i_Volumn(iX, iY, iZ) << endl;
 return;
}

int i_Volumn(int iX, int iY, int iZ)
{ return iX * iY * iZ; }

int main(void)
{
 cHexahedron cHex[3];
 for(int i = 0; i < 3; i++)
 {
  cout << i + 1 << "번째 ";
  cHex[i].v_GetValue();
 }
 
 for(i = 0; i < 3; i++)
 {
  cout << i + 1 << "번째 ";
  cHex[i].v_Print();
 }

 return 0;
}


해설
  - 클래스와 함수 구조입니다.

사용자 삽입 이미지
  -  iX 와 iY, IZ 는 private 로 보호된 맴버 변수 입니다. private 는 클래스의 맴버가 아닌 다른 외부 함수에서 불러다 쓸수 없습니다. 이를 정보 보호 / 은닉이라 하는데 자료의 효율적인 관리를 목적으로 만들어진 것입니다. 예외적으로 friend 함수를 두어 private 맴버라도 불러다 쓸수 있게 합니다. public 영역에서 friend 를 선언하여 남용을 방지 합니다.

  - 맴버 함수에서는 부른 객체 자신을 가리키는 this 객체가 기본적으로 존재 합니다. 이를 생략해서 그냥 iX, iY, iZ 를 써서 쓸수 있지만 이를 표기하여 this.iX this.iY this.iZ 로 쓸수 있습니다. 맴버 함수에서는 자신이 속한 클래스 객체의 맴버 변수를 쓸수 있으므로 private 로 선언된 맴버 변수도 자유롭게 쓸수 있습니다.

  - "i + 1 번째 " 만 따로 출력하여 공통된 부분의 출력부를 최소화 했습니다.

참고
  - 클래스는 C++ 의 가장 두들어진 객체지향적 특징입니다. C 에서는 극히 일부 기능을 구조체에서 제공하고 있습니다. 클래스는 잠깐 공부하기 보다 아래 페이지에서 자세히 공부 하시는게 이후 C++ 의 클래스를 이해하시는데 도움이 될 것입니다.

  - http://www.winapi.co.kr/clec/cpp4/cpp4.htm : winapi 에서 제공하는 C++ 문법

Posted by 카켈



목적
  - 최소공배수와 최대공약수를 구하기 위한 조건과 반복문 나눗셈 사용을 익힌다.

문제
사용자 삽입 이미지

풀이

#include <iostream>

using namespace std;

int main(void)
{
 int iA, iB, iLCM, iGCD, iStart, iEnd ; // iLCM : 최소공배수 iGCD : 최대공약수
 iA = iB = iLCM = iGCD = iStart = iEnd = 0;

 cout << "두 정수값을 입력하세요 : ";
 cin >> iA >> iB;

 iStart = iA <= iB ? iA : iB;
 iEnd = iA <= iB ? iB : iA;
 iA = iStart;
 iB = iEnd;

 // LCM, GCD 계산
 for(iStart = 1; iStart <= iEnd; iStart++)
  if(iA % iStart == 0 && iB % iStart == 0)
   iGCD = iGCD < iStart ? iStart : iGCD;

 for(iStart = iB; iStart <= iA * iB; iStart++)
  if(iStart % iA == 0 && iStart % iB == 0)
  {
   iLCM = iStart;
   break;
  }
 
 cout << iA << " 과 " << iB << " 의 최대공약수 : " << iGCD << endl;
 cout << iA << " 과 " << iB << " 의 최소공배수 : " << iLCM << endl;

 return 0;
}

해설
  - 최대공약수 : 1에서 큰수까지 1씩 증가하며 가는데 작은수 와 큰수 모두 나머지가 0인 수
  - 최소공배수 : 큰수에서 두수의 곱까지 1씩 증가하는데 그수와 두수 모두의 나머지가 0인 수

참고
  - 유사 문제

Posted by 카켈