[C++] 02. 제어문과 함수

78141 단어 cppcpp

2.1 선택문

- if 문을 사용한 홀수와 짝수 판별하기

  • 선택문
    - 조건의 만족 여부에 따라 수행되는 부분 결정
    - if 문, switch문
  • if 문
    - if 문, if ~ else 문
#include <iostresam>
using namespace std;

int main()
{
	int num;
    
    cout << "정수값 입력 : ";
    cin >> num;
    
    if (num % 2 == 1)
    	cout << num << " : " << "홀수" << endl;
    else
    	cout << num << " : " << "짝수" << endl;
        
    return 0;
}
[결과]
정수값 입력 : 123
123 : 홀수

- if ~ else if ... else 문

  • if ~ else if ... else 문
    - if문 역시 하나의 문장
    - if 문 내에 다시 if문이 올 수도 있고, else 문 다음에 다시 if문이 올 수도 있음
    - {} 를 사용하면 이해하기 쉬움
#include <iostream>
using namespace std;

int main()
{
	int num, remainder3;
    
    cout << "정수값 입략 : ";
    cin >> num;
    remainder3 = num % 3;	// 3으로 나눈 나머지
    
    if (remainder3 == 0)	// 나머지가 0
    	cout << num << " : 3으로 나눈 나머지가 0입니다." << endl;
    else if (reaminder3 ==1)	// 나머지가 1
    	cout << num << " : 3으로 나눈 나머지가 1입니다." << endl;
    else
    	cout << num << " : 3으로 나눈 나머지가 2입니다. << endl;
        
    return 0;
}
[결과]
정수값 입력 : 123
123 : 3으로 나눈 나머지가 0입니다.

- if ~ else 문의 복잡한 사용

  • 다음 프로그램의 실행 결과는?
    - 가독성을 높이기 위해 {} 사용
    - 들여쓰기를 적절히 사용
#include <iostream>
using namespace std;

int main()
{
	int num1 = 7, num2 = 7;
    
    if (num1 == 1)
    	if (num2 == 2)
        	num1 += num2;
    else	// 어떤 if 문에 대한 else 문인가?
    	num1 -= num2;
        
    cout << "num1 : " << num1 << endl;
    
    return 0;
}
[결과]
num1 : 7

- switch 문

  • switch문
    - condition과 같은 값의 case문 실헹
    - 동작 방식 주의
switch (condition)	// condition : 평가 결과가 정수형 값(char, int, bool)이어야 함
{
	case val1 :	// val1 : 상수값 또는 상수 표현식
    	statements
    case val2 :
    	statements
    ......
    default : 
    	statements
}
#include <iostream>
using namespace std;

int main()
{
	int num, remainder3;
    
    cout << "정수값 입력 : ";
    cin >> num;
    remainder3 = num % 3;	// 3으로 나눈 나머지
    
    switch (remainder3)
    {
    	case 0:	// 나머지가 0
        	cout << num << " : 3으로 나눈 나머지가 0입니다." << endl;
            break;
        case 1:	// 나머지가 1
        	cout << num << " : 3으로 나눈 나머지가 1입니다." << endl;
            break;
        default: // 나머지가 2
        	cout << num << " : 3으로 나눈 나머지가 2입니다." << endl;
            break;
    }
    
    return 0;
}
[결과]
정수값 입력 : 30
30 : 3으로 나눈 나머지가 0입니다.

2.2 반복문

- 1부터 1000까지 더하기 : for 문

  • 반복문
    - 특정 조건을 만족하는 동안 해당 작업 반복 수행
    - for 문, while 문, do while 문
  • for 문
#include <iostream>
using namespace std;

int main()
{
	int result = 0;	// 0으로 초기화
    int i;
    
    for (i = 1; i <= 1000; i++)	// 1부터 100까지의 값들을
    	result = result + i;	// Result에 더해 줌
        
    cout << "1부터 1000까지의 합 : " << result << endl;
    
    return 0;
}
[결과]
1부터 1000까지의 합 : 500500

- 1부터 1000까지 더하기 : while 문

  • while
int main()
{
	 int result = 0;	// 0으로 초기화
     int i =1;	// 1로 초기화
     
     while (i <= 1000)	// for(i = 1; i <= 1000; i++)
     {
     	result = result + i;	// 1부터 1000까지 result에 더해줌
        i++
     }
     
     cout << "1부터 1000까지의 합 : " << result << endl;
     
     return 0;
}
[결과]
1부터 1000까지의 합 : 500500

- 1부터 1000까지 더하기 : do~while 문

  • do ~ while문 (적어도 1번 실행)
int main()
{
	int result = 0;	// 0으로 초기화
    int i = 1;	// 1로 초기화
    
    do	// while (i <= 1000)
    {
    	result = result + i	// 1부터 1000까지 result에 더해 줌
        i++
    } while (i <= 1000);
    
    cout << "1부터 1000까지의 합 : " << result << endl;
    
    return 0;
}
[결과]
1부터 1000까지의 합 : 500500

- 반복문의 선택 방법

  • 반복문의 선택 -> 연습을 통한 습득 필요
    - 특정 범위의 데이터 처리 : for문
    - 범위가 정해져 있지 않은 반복 작업 : while문
    • 반드시 한 번 이상 실행 : do ~ while문
  • ex) 특정 조건을 만족할 떄까지 반복 수행
    - 1, 2, 3, 4, 5 중 하나 입력, 해당 개수만큼 문자열 출력 -> 5 입력 시 종료
#include <iostream>
using namespace std;

int main()
{
	int result =0;	// 0으로 초기화
    int i = 1;	// 1로 초기화
    
    do	// while(i <= 1000)
    {
    	result = result + i;	// 1부터 1000까지 result에 더해 줌
        i++
    } while(i <= 1000)
    
    cout << "1부터 1000까지의 합 : " << result << endl;
    
    return 0;
}

2.3 분기문

- break 문

  • break 문
    - 자신이 포함된 반복문을 탈출하는 문장
    - 반복문이 중첩되어 나타날 경우에는 자신을 포함하고 있는 반복문들 중 가장 가가운 반복문을 탈출
int main()
{
	for(int dan = 2; dan <= 9; dan++)
    {
    	for(int i=1; i<=9; i++)
        {
        	if(dan % 2 == 0)	// 짝수단이라면
            	break;			// 가장 가까운 for문을 빠져나옴
                
            cout << dan << "*" << i << "=" << dan * i << endl;
        }
    }
    
    return 0;
}

- continue 문

  • continue 문
    - 해당 반복문 내에 포함된 continue 문 이후의 문장들을 실행하지 않고 그 다음으로 바로 건너뜀
int main()
{
	for(int dan =2; dan<=9; dan)
    {
    	if(dan % 2 == 0)	// 짝수단이라면
        	continue;		// 해당 단(i)을 skip함
        
        for(int i = 1; i <= 9; i++)
        {
        	cout << dan << "*" << i << "=" << dan * i << endl;
        }
    }
    
    return 0;
}

- return 문

  • return 문
    - 함수 탈출 시 특정값 반환
    - 함수의 반환 타입이 void인 경우 단순히 함수 탈출
void GuGu(int dan)
{
	if(dan % 2 == 0)	// 짝수단이라면
    	return;			// 출력하지 않고 바로 반환
        
    for(int i = 1; i <= 9; i++)
    {
    	cout << dan << "*" << i << "=" << dan * i << endl;
    }
}

int main()
{
	for(int dan = 2; dan <= 9; dan++)
    	GuGu(dan);
        
    return 0;
}

- goto 문

  • goto문
    - 특정 레이블로 이동(될 수 있으면 사용 x)
int main()
{
	for(int dan = 2; dan <= 9l dan++)
    {
    	if(dan % 2 == 0)	// 짝수단이라면
        	goto next;		// next 레이블로 점프
            
        for(int i = 1; i <= 9; i++)
        	cout << dan << "*" << i << "=" << dan * i << endl;
            
        next: ;	// next 레이블
    }
    
    return 0;
}

2.4 함수와 변수

- 덧셈, 뺄셈 계산기 만들기

  • 전역 변수
    - 함수 외부에 위치
    - 함수들이 공유
  • 지역 변수
    - 함수 내에 위치, 매개 변수
    - 해당 지역 내에서만 사용 가능
#include <iostream>
using namespace std;

int g_result = 0;	// g_result : 전역변수

void Plus(int num)	// num : 지역변수
{
	g_result += num;
}

void Minus(int num)
{
	g_result -= num;
}

int main()
{
	Plus(5); Minus(10); Minus(3); Pluse(4);
    cout << "최종 결과 : " << g_result << endl;
    
    return 0;
}
[결과]
최종결과 : -4

- 변수의 선언 위치

  • 전역
  • 지역
    - 블록 내 : { }
    - 제어문
int g_var1;					// 전역변수
int Sum(int num1, int num2)	// 함수 매개변수
{
	g_var1 = 0;
    
    for(int i = num1; bool j = (i <= num2); i++)	// for 초기화문 및 조건문
    	g_var1 += i;
        
    while(bool i = (num1 <= num2))	// while 조건문
    {
    	int temp = num2;			// while 복합문 내 변수
        g_var1 += temp;
        num2--;
    }
    return g_var1;
}

int g_var2;
int main()
{
	int num1, num2;				// 전역 변수
    cout << "정수 2개 입력 : ";	// 함수 내 변수
    cin >> num1 >> num2;
    g_var2 = Sum(num1, num2);
    int num3 = g_var;			// 함수 내 변수
    cout << "최종 결과 : " << num3 << endl;
    return 0;
}
[결과]
정수 2개 입력 : 10 20
최종 결과 : 330

- 변수의 사용 가능 영역(Scope)

  • Scope : 변수가 사용될 수 있는 영역(범위)
    - 해당 변수가 선언된 이후에 사용 가능
    - 해당 변수가 선언된 지역 내에서만 사용 가능
  • 이름 은닉 (name hiding)
    - 어떤 지역에서는 이전에 선언된 변수와 동일한 이름으로 변수가 선언될 때, 해당 지역에서는 이전 변수의 사용이 불가능 -> 전역 변수는 가능
int var1 = 0;

int main()
{
	int var2 = 100;
    int var1 = 200;
    
    {
    	int var2 =200;
        int var3 = var1 + var2;
        
        var1 = var2 + var3;
    }
    
    cout << "var1 : " << var1 << endl;	// 어떤 var1인가?
    cout << "var2 : " << var2 << endl;	// 어떤 var2인가?
    // cout << "var3 : " << var3 << endl;
    // 20라인의 var3은 해당 지역 종료 후 사라짐
    cout << "::var1 : " << ::var1 << endl;	// 전역 변수 var1
    
    return 0;
}
[결과]
var1 : 600
var2 : 100
::var1 : 0

- 변수의 수명 (lifetime)

  • Storage duration : 어떤 변수의 메모리 할당 시점 ~ 해제 시점
변수 종류설명
정적(static) 변수- 프로그램 종료시 해제
- 초기화 문장은 첫 번째 호출 시에만 실행
- 초기화 문장이 없다면 자동으로 0으로 초기화
자동(auto) 변수- static이 아닌 지역 변수
- 해당 지역 탈출 시 해제
- 초기화 문장이 없다면 쓰레기값으로 초기화
동적(dynamic) 변수- new 연산자와 delete 연산자에 의해 소명 및 생성
int g_var;	// 자동으로 0으로 초기화

void Func(int param)
{
	static int s_num = 100;	// static 지역 변수
    int a_num = 100;		// auto 지역 변수
    
    g_var++;
    s_num++;
    a_num++;
    
    cout << "g_var : " << g_var << ", ";
    cout << "s_num : " << s_num << ", ";
    cout << "a_num : " << a_num << endl;
}

int main()
{
	for(int i = 0; i < 5; i++)
    	Func(i);
        
    return 0;
}
[결과]
g_var : 1, s_num : 101, a_num : 101
g_var : 2, s_num : 102, a_num : 101
g_var : 3, s_num : 103, a_num : 101
g_var : 4, s_num : 104, a_num : 101
g_var : 5, s_num : 105, a_num : 101

2.5 함수 오버로딩

- Sum 함수 작성

  • int 값 2개 사이의 값들을 더하는 함수, double 값 2개를 더하는 함수
    - int : ISum 함수
    - double : DSum 함수
  • 둘 다 Sum이라는 함수명을 사용할 수는 없을까?
    -> 함수 오버로딩 (function overloading)
#include <iostream>
using namespace std;	// std라는 namespace의 내용을 불러옴

int ISum(int num1, int num2)
{
	int result = 0;
    
    for(int i = num1; i <= num2; i++)	// num1 <= num2 로 가정
    	result += i;
      
    return result;
}

double DSum(double num1, double num2)
{
	return(num1 + num2);
}

int main()
{
	cout << "ISum(1, 10) 	 : " << ISum(1, 10) << endl;
    cout << "DSum(1.0. 10.0) : " << DSum(1.0, 10.0) << endl;
    
    return 0;
}
[결과]
ISum(1, 10)		: 55
DSum(1.0, 10.0) : 11

- 함수 오버로딩을 사용한 Sum 함수 작성

  • 함수 오버로딩 (overloading)
    - 동일한 이름으로 여러 개의 함수를 작성할 수 있음
    - 함수의 구분
    • 함수 이름이 다르거나
    • 매개변수의 개수나 타입이 달라야 함
  • 다음은 함수 오버로딩인가?
    - int Func(int n);
    - char Func(int n);
    -> 오버로딩이 아니다
int Sum(int num1, int num2)
{
	int result = 0;
    
    for(int i = num1; i <= num2; i++)	// num <= num2 로 가정
    	result += i;
        
    return result;
}

double Sum(double num1, double num2)
{
	return(num1 + num2);
}

int main()
{
	cout << "Sum(1, 10)		: " << Sum(1, 10) << endl;
    cout << "Sum(1.0, 10.0)	: " << Sum(1.0, 10.0) << endl;
    
    return 0;
}
[결과]
Sum(1, 10)		: 55
Sum(1.0, 10.0)  : 11

2.6 디폴트 인자

- 거듭제곱을 구하는 power 함수 작성

  • 매개변수가 1개인 경우 x의 2승, 2개인 경우 x의 y승 반환
    - 함수 오버로딩을 사용한 power 함수 작성
  • 디폴트 인자의 활용
    - int Power(int x, int y = 2);
    - Power(3) -> 3의 2승 반환
    - Power(3,4) -> 3의 4승 반환
    - 디폴트 인자값은 마지막부터 설정할 수 있음
    - 모호한 상황 주의
    • int Power(int x), int Power(int x, int y = 2)
int Power(int x)		// x의 2승
{
	return(x * x);
}

int Power(int x, int y)	// x의 y승
{
	int result = 1;
    
    for(int i = 0; i < y; i++)
    	result *= x;
        
    return result;
}

int main()
{
	cout << "Power(3)	 : " << Power(3) << endl;		// 3의 2승
    cout << "Power(3, 3) : " << Power(3, 3) << endl; 	// 3의 3승
    
    return 0;
}
[결과]
Power(3)	: 9
Power(3, 3) : 27

2.7 재귀 호출

- 두 수 사이의 값들 합산하기

  • 재귀호출
    - 현재 실행 중인 지점까지 사용된 이전 함수들 중 하나를 다시 호출
    - 재귀 함수 : 재귀 호출을 포함하는 함수
  • 두 수 사이의 값들 합산
    - 재귀 함수의 활용
    1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +10 => 1, 10 사이 값의 합
int Sum(int num1, int num2)
{
	if(num1 == num2)
    	return num2;
    else
    	return (num1 + Sum(num1 + 1, num2));
}

int main()
{
	cout << "Sum(1, 10)	  : " << Sum(1, 10) << endl;
    cout << "Sum(10, 100) : " << Sum(10, 100) << endl;
    
    return 0;
}
[결과]
Sum(1, 10)	 : 55
Sum(10, 100) : 5005

- 재귀 호출을 사용하여 factorial 구하기

  • factorial 구하기
    - 재귀 호출 연습을 위한 대표적인 문제
    - Fact(5) = 5 4 3 2 1
    - Fact(0) = 1
int Fact(int num)
{
	if(num == 0)
    	return 1;
    else
    	return(num * Fact(num - 1));
}

int main()
{
	cout << "3! = " << Fact(3) << endl;
    cout << "%! = " << Fact(5) << endl;
    cout << "0! = " << Fact(0) << endl;
    
    return 0;
}
[결과]
3! = 6
5! = 120
0! = 1

2.8 인라인 함수

- 매크로 함수와 일반 함수 복습

// 매크로로 구현한 경우
#defune MIN(X, Y) ((X) < (Y) ? (X) : (Y))	// 최소값 반환
Int main()
{
	cout << MIN(4, 5) << endl;
    cout << MIN((2 + 3), (1 + 2)) << endl;
    return 0;
}
// 함수로 구현한 경우
int MIN(int X, int Y)
{
	return(X < Y ? X : Y);	// 최소값 반환
}

int main()
{
	cout << MIN(4, 5) << endl;
    cout << MIN((2 + 3), (1 + 2)) << endl;
    return 0;
}
[결과]
4
3

- inline 함수

  • inline 함수
    - 매크로와 유사 : 함수 호출 문장을 해당 함수의 코드로 대치하도록 요구
    - 대치 여부는 컴파일러가 결정
    - 함수 정의 시 inline 키워드 추가
    - inline int MIN(int X, int Y){return((X) < (Y) ? (X) : (Y));}
  • factorial 재귀 함수를 inline 함수로 작성한다면?
inline int Fact(int num)	// 재귀 호출 함수
{
	return((num == 0) ? 1 : num * Fact(num - 1));
    // 5! = 5 * 4!
}

int main()
{
	cout << "5! = " << Fact(5) << endl;
	return 0;
}
[결과]
5! = 120

2.9 네임스페이스 : 고전 C++과 표준 C++

- 네임스페이스의 필요성

  • 다양한 라이브러리를 사용할 때 생길 수 있는 문제잠 : 어떤 Sum 함수?
  • 네임스페이스(이름공간)
    - 특정 식별자에 의한 그룹 (여러 식별자를 하나의 그룹으로 만듦)\

- 네임스페이스 만들고 사용하기

  • 네임스페이스 만드는 방법
    - namespace 네임스페이스명 {......}
  • 네임스페이스 사용 방법
    - 네임스페이스명::식별자
  • 전역 네임스페이스
    - ::Sum(3, 4)와 같이 사용 가능
namespace Microsoft	// Microsoft 네임스페이스 작성
{
	int g_var;
    int Plus(int x, int y) {return(x + y);}
    int Minus(int x, int y)	{return(x - y);}
}

namespace Google	// Google 네임스페이스 작성
{
	int g_var;
    int Plus(int x, int y) {return(x + y);}
    int Minus(int x, int y)
}

int Google ::Minus(int x, int y)	// Google 네임스페이스의 Minus 함수 작성
{
	return(x - y);
}

int main()	// 네임스페이스 이름으로 접근
{
	Microsoft::g_var = Microsoft::Minus(5, 2);
    cout << Microsoft::g_ var << endl;
    return 0;
}
[결과]
3

- using 선언

  • using 선언
    - 다른 네임스페이스에 있는 식별자를 현재 네임스페이스에서 사용
    - using 키워드를 사용한 네임스페이스에서 유효
    - using Microsoft::Minus;
    - using namespace Microsoft; -> Microsoft의 모든 식별자를 현재 위치에서 선언
#include <iostream>
// using namespace std;

using std::cout;	// 전역예서 cout를 사용할 수 있음
using std::endl;	// 전역에서 endl을 사용할 수 있음

int main()
{
	cout << "표준 C++" << 두이;
    // std::cout << "표준 C++" << std::endl;	// using 선언 없을 떄
}
[결과]
표준 C++

- C++에서 기존 C 라이브러리의 활용 방법

  • Visual C++
    - 기존 C 라이브러리를 그대로 사용 가능
    - C++ 스타일 : 헤더 파일에 C접두사가 붙고 확장자가 없음(예, cstdio)
    - 헤더 파일에 확장자가 없음
  • cstdio 파일 : stdio.h 파일을 그대로 포함, 식별자를 std 네임스페이스로 포함
    - using 선언을 통해 기존과 동일하게 사용 가능하도록 만들어짐
    - Visual C++ 6.0 : 단순히 stdio.h 파일만 포함 -> using 선언 사용 불가
// #include <stdio.h>
#include <cstdio>
using namespace std;

int main()
{
	printf("C++ Programming\n");
    return 0;
}
[결과]
C++ Programming

- 중첩 네임스페이스

  • 중첩 네임스페이스
    - 네임스페이스 내에 또 다른 네임스페이스 선언 가능
    - CompanyB::DeptC::Func1()과 같이 사용
namespace CompanyA	// 네임스페이스 CompanyA 작성
{
	int g_var_b
    void Func1() { cout << "CompanyA::Func1" << endl; }
    void Func2() { cout << "CompanyA::Func2" << endl; }
}

namespace CompanyB	// 네임스페이스 CompanyB 작성
{
	using namespace CompanyA;	// 네임스페이스 CompanyA를 CompanyB로 포함
    int g_var_b;
    void Func1() {cout << "CompanyB::Func1" << endl;}
    
    namespace DeptC	// Company 내에 네임스페이스 DeptC 작성
    {
    	void Func1() {cout << "CompanyB::DeptC::Func1" << endl;}
    }
}

int main()
{
	CompanyB::Func1();
    CompanyB::Func2();	// 실제로는 CompanyA의 Func2 함수 실행
    CompanyB::DeptC::Func1();
    return 0;
}
[결과]
CompanyB::Func1
CompanyA::Func2
CompanyB::DeptC::Func1

좋은 웹페이지 즐겨찾기