C++의 개념

C언어 + 객체지향 개념 = C++

C++은 C 언어를 포함한다. 때문에 C언어로 작성된 대부분의 프로그램은 C++ 컴파일러로도 컴파일이 가능하다.

그러나 C++은 C언어가 지니지 않는 문법적 특성도 제법 지니고 있다.


C언어와 C++의 차이점

  • 입출력과 관련된 헤더 파일의 변경

    새로운 C++ 표준의 도입으로 인해서 C++의 표준 라이브러리에도 적지 않은 변화가 있었다.
    그리고 새로운 표준 라이브러리의 사용을 목적으로 하는 헤더파일의 포함에는 확장자를 생략하기로 하였다.
  C언어 C++
출력 printf(); std::cout;
입력 scanf(); std::cin;

 

 

  • 지역변수 선언 위치의 자유로움

    C언어로 프로그램을 작성하는 경우에는 함수를 정의함에 있어서 지역변수의 선언이 항상 제일 먼저 등장해야만 했다. 그러나 C++의 지역변수 선언은 함수 내 어디든 삽입이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
int main(void)
{
    //[START] C언어에서의 지역변수 선언 필수 지역
    int val1, val2;
    int result=0;
    //[E N D] C언어에서의 지역변수 선언 필수 지역
    
    std::cout<<"두 개의 숫자입력: ";
    std::cin>>val1>>val2;
    
    if(val1<val2)
    {
        for(int i=val1+1; i<val2; i++)
            result+=i;
    }
    else
    {
        for(int i=val2+1; i<val1; i++)
            result+=i;
    }
    
    std::cout<<"두 수 사이의 정수 합: "<<result<<std:endl;
    
    return 0;
}
cs

//실행결과

//실행결과

두 개의 숫자입력: 3 7

두 수 사이의 정수 합: 15

 

 

  • 함수의 오버로딩(function overloading) - 중복 함수

    같은 이름의 함수를 여러 개 정의하고, 매개변수의 유형과 개수를 다르게 해 다양한 유형의 호출에 응답하는 것.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
    오버로딩 없이 동일한 기능에 다른 매개 변수를 사용하는 함수를 만드는 방법
    약간 다른 이름으로 여러 함수를 정의한다.
*/
 
int addInteger(int x,int y)
{
    return x+y;
}
 
double addDouble(double x, double y)
{
    return x+y;
}
 
 
/*
    함수 오버 로딩을 사용 시 다른 매개 변수를 취하는 add() 함수를 선언할 수 있다.
*/
 
int add(int x, int y);           //Integer version
double add(double x, double y);  //floating point version
 
//매개 변수의 수가 다른 add()함수도 정의 가능하다.
int add(int x, int y, int z)
{
    return x+y+z;
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//사용 할 수 없는 함수의 오버로딩 기능
int getRandomValue();
double getRandomValue();
 
//결과는 컴파일 오류.
 
 
//1번 해결: 함수에 서로 다른 이름을 지정할 것
int getRandomint();
double getRandomDouble();
 
//2번 해결: 함수가 void를 반환하도록 하고 반환 값을 호출자에게 out 참조 매개 변수로 전달하도록 하는 것
void getRandomValue(int& out);
void getRandomValue(double& out);
cs

위와 같이 처리해야 하는 이유는 오버로딩에서는 함수의 반환 타입이 고려되지 않기 때문이다.

합수는 인수에만 기반하여 호출되는데, 반환 값이 포함된 경우 함수의 어떤 버전이 호출되었는지 쉽게 알기가 어렵다.

 

 

  • 매개변수의 기본 값(Default Value) 추가

    C++ 함수에는 '디폴트 값'이라는 것을 설정할 수 있다. 이것은 말 그대로 기본적으로 설정되어 있는 값이다.
    매개변수에 디폴트 값이 설정되어 있으면 선언된 매개변수의 수보다 적은 수의 인자전달이 가능하다.
    그리고, 전달되는 인자는 왼쪽에서부터 채워져 나가고, 부족분은 디폴트 값으로 채워진다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* DefaultValue2.cpp */
#include <iostream>
int Adder(int num1=1int num2=2);   //디폴트 값은 함수의 선언 부분에만 표현하면 된다.
 
int main(void)
{
    std::cout<<Adder()<<std::endl;
    std::cout<<Adder(5)<<std::endl;
    std::cout<<Adder(3,5)<<std::endl;
    return 0;
}
 
int Adder(int num1, int num2)
{
    return num1+num2;
}
cs

디폴트 값의 선언이 함수의 선언부에 위치해야 하는 이유는 컴파일시 "std::cout<<Adder()<<std::endl;" 문장의 실행이 가능하게 하기 위함이다. 위와 같이 디폴트 값을 전부 지정할 수도 있지만, 부분적인 디폴트 값 설정도 가능하다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int YourFunc(int num1; int num2=5int num3=7){ . . .}
 
YourFunc(10);       //10,  5, 7
YourFunc(1020);   //10, 20, 7
 
 
//디폴트 값 지정이 가능한 함수
int YourFunc(int num1, int num2, int num3=30) { . . . }
int YourFunc(int num1, int num2=20int num3=30) { . . . }
int YourFunc(int num1=10int num2=20int num3=30) { . . . }
 
//디폴트 값 지정이 불가능한 함수
int WrongFunc(int num1=10int num2, int num3) { . . . }
int WrongFunc(int num1=10int num2=20int num3) { . . . }
cs

하지만, 오른쪽 매개변수의 디폴트 값을 비우는 형태로는 디폴트 값을 지정할 수 없다. 함수에 전달되는 인자가 왼쪽에서부터 오른쪽으로 채워지기 때문에 반드시 오른쪽 매개변수의 디폴트 값부터 채우는 형태로 정의해야 한다.

 

 

  • 인라인(Inline) 함수 - 확장 함수

    프로그램 코드라인 안으로 들어가 버린 함수로, C언어에서 사용하는 매크로 함수의 장점은 유지하고,
    단점인 어려운 정의 부분을 해결한 함수이다.

    매크로를 이용한 함수의 인라인화는 전처리기에 의해 처리되지만,
    키워드 Inline을 이용한 함수의 인라인화는 컴파일러에 의해 처리가 된다.

    따라서 컴파일러는 함수의 인라인화가 오히려 성능에 해가 된다고 판단할 경우, 이 키워드를 무시해버리거나 필요한 경우 일부 함수를 임의로 인라인 처리하기도 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**********************************
    매크로 함수
***********************************/
#include <iostream>
#define SQUARE(x) ((x)*(x))
 
int main(void)
{
    std::cout<<SQUARE(5<<std:endl;
    return 0;
}
 
/**********************************
    C++ 기반의 인라인 함수 정의
***********************************/
#include <iostream>
 
inline SQUARE(int x)
{
    return x*x;
}
 
int main(void)
{
    std::cout<<SQUARE(5)<<std::endl;
    std::cout<<SQUARE(12)<<std::endl;
    return 0;
}
cs
//result
25
144

 

단, 매크로 함수에서 데이터 손실이 발생하지 않던 장점이 인라인 함수에서는 적용되지 않는다.

1
2
3
4
5
6
7
8
9
10
/**************************************
    데이터 손실 예제
**************************************/
#define SQUARE(x) ((x)*(x))
 
std::cout<< SQUARE(12);    // int형 함수호출
//변환| std::count<< ((12)*(12));
 
std::cout<< SQUARE(3.15);  // double형 함수호출
//변환| std::count<< ((3.15)*(3.15));
cs

 

 

  • 이름공간(namespace)의 추가

    이름공간과 범위 지정 연산자 ::(scope)의 추가로 동일한 이름의 func을 지정하여 사용할 수 있게 되었다.
    이름공간은 중첩하여 사용 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
 
namespace Koscom1
{
    void SimpleFunc(void);
}
 
namespace Koscom2
{
    void SimpleFunc(void);
}
 
int main(void)
{
    Koscom1::SimpleFunc();
    Koscom2::SimpleFunc();
    return 0;
}
 
void Koscom1::SimpleFunc(void)
{
    std::cout<<"Koscom1이 정의한 함수"<<std::endl;
}
 
void Koscom2::SimpleFunc(void)
{
    std::cout<<"Koscom2이 정의한 함수"<<std:endl;
}
cs

 

콘솔 입출력 진행 시 사용하던 것들도 이름공간을 이용하여 선언된 것이라는 것을 유추해 볼 수 있다.
이름공간을 명시하는 방법에는 using도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
 
int main(void)
{
    int num=20;
    cout<<"Hello World!"<<endl;
    cout<<"Hello "<<"World!"<<endl;
    cout<<num<<' '<<'A';
    cout<<' '<<3.14<<endl;
    return 0;
}
cs
//result
Hello World!
Hello World!
20 A 3.14

 

using 선언을 일괄적으로 하는 방법은 "using namespace std;"를 해주면 된다.

하지만, 이런 일괄선언 방식은 이름충돌이 발생할 확률이 상대적으로 높아지는 현상이 발생한다.

따라서, 무조건 편한 것만을 선호하기 보다는 적용 할 소스에 적정하게 판단하여 사용하는 것이 필요하다.

 

이름공간의 별칭 지정이 가능하므로, 중첩되는 이름공간이 많아졌을 때는

호출 시 편리성을 촉진시키기 위해 호출하는 이름공간에 별칭을 부여 할 수 있다.

가령 AAA::BBB::CCC::num1 = 10;을 호출한다면 namespace ABC=AAA::BBB::CCC;로 별칭을 선언 할 수 있다.

ABC::num1=10;도 동일하게 변수로 사용 할 수 있다.

 

범위지정 연산자 :: (scope)로 중복 이름의 전역변수 호출도 가능하다.

1
2
3
4
5
6
7
8
int val=100;    // 전역변수
 
int SimpleFunc(void)
{
    int val=20// 지역변수
    val+=3;     // 지역변수 val의 값 3 증가
    ::val+=7;   // 전역변수 val의 값 7 증가
}
cs

 

 

  • 새로운 자료형 bool의 등장

    bool에서는 '참'을 의미하는 true와 '거짓'을 의미하는 false가 있다.
    이것을 가리켜 bool형 데이터라 한다.
    그리고, bool은 int, double과 마찬가지로 기본자료형의 하나이기 때문에 bool형 변수로 선언이 가능하다.

    true와 false는 그 자체로 참과 거짓을 의미하는 데이터이기 때문에,
    이들 데이터의 저장을 위한 자료형이 별도로 정의되어 있는 것은 당연하다.
1
2
bool isTrueOne=true;
bool isTrueTwo=false;
cs

 

 

  • 참조자(Reference) = 별칭

    참조자는 자신이 참조하는 변수를 대신할 수 있는 또 하나의 이름이다.
    참조자의 수에는 제한이 없으며, 참조자르 대상으로도 참조자를 선언할 수 있다.
    단, 참조자의 선언 가능 범위는 정해져 있으며 변수와 비슷한 기능을 하지만, 혼자 스스로 선언 될 수 없다.

    무조건 변수를 참조하여 선언해야 한다.

프로그램의 구조

프로그램은 일반적으로 세 가지 기본 요소로 구성된다.

명령문(statement)

표현식(expression)

함수(function)

 

 

  • 명령문(statement)

    프로그램에서 가장 일반적인 구조이며 C++에서 명령문은 가장 작은 단위이다.
    생각을 전달하기 위해 사용하는 문장과 유사하며, C++에서는 컴파일러에게 작업을 수행하기 위해 명령문을 작성한다.
1
2
3
4
5
/* 명령문 예제 */
 
int x;          //선언문(declaration statement), x가 정수(int) 형태의 값을 보유하는 변수임을 컴파일러에게 알린다.
x=5;            //변수 x에 값 5를 할당하여 나중에 이 값을 사용할 수 있도록 하는 명령문이다.
std::cout << x; //변수 x의 값을 콘솔에 출력하는 명령문이다.
cs

 

  • 표현식(expression)

    컴파일러는 표현식을 해석할 수 있다. 표현식은 수행할 계산을 지정한다.
    예를 들어, 프로그램에서 2+3 값은 5로 평가되는 표현식이다.

    표현식은 리터럴(literal) 값 2나 텍스트를 나타내는 "Hello, world" 및 변수, 수학 연산자(+)와 함수 호출을 포함한다.
    x=5는 변수 x에 5의 값을 할당하는 유효한 표현식이다. (세미콜론은 없다.)

    표현식은 명령문 내에서 사용되기 때문에 자체적으로 컴파일 될 수 없다.
    예를 들어 x=5 라는 표현식을 컴파일하려고 하면 세미콜론이 빠졌으므로 에러가 발생한다.
1
2
3
4
5
6
7
2
"Hello, world"
x
2+3
x=5
(2+x)*(y-3)
std::cout << x
cs

 

  • 함수(Function)

    C++에서 명령문은 함수라고 하는 단위로 그룹화된다. 즉, 함수는 순차적으로 실행되는 명령문의 집합이다.
    모든 C++ 프로그램에는 main이라는 특수 함수가 있어야 하며, 프로그램이 실행될 때 main 함수 내부의 첫 번째 명령문부터 시행이 시작된다.

'C++' 카테고리의 다른 글

연산자 오버로딩  (1) 2019.11.27
객체와 friend 함수  (0) 2019.11.27
생성자와 소멸자  (0) 2019.11.27
메모리 구조와 동적 메모리 할당  (0) 2019.11.27

+ Recent posts