Skip to content

1. C++ 프로그램(C++ Program)


1. 키워드

  • 프로그래밍(Programming)
  • 소스 파일(Source File), 오브젝트 파일(Object File), 실행 파일(Executable File)
  • 선행처리기(Preprocessor), 컴파일러(Compiler), 링커(Linker)
  • 네임스페이스(Namespace)
  • iostream 헤더 파일


2. C++ 프로그래밍

  • 프로그래밍이란 목적에 맞는 알고리즘으로부터 프로그래밍 언어를 사용하여 구체적인 프로그램을 작성하는 과정을 의미한다.
  • 이렇게 작성된 소스 파일은 먼저 실행 파일로 변환되어야 실행할 수 있다.


  • C++의 소스 파일에서 실행 파일을 생성하는 순서는 다음과 같이 진행된다.


001


  • 소스 파일 → 선행처리기 → 컴파일러 → 오브젝트 파일 → 링커 → 실행 파일


1] 소스 파일의 작성

2] 선행처리기에 의한 선행처리

3] 컴파일러에 의한 컴파일

4] 링커에 의한 링크

5] 실행 파일의 생성


1) 소스 파일의 작성

  • 프로그래밍에서 가장 먼저 해야 할 작업은 바로 프로그램을 작성하는 것이다.
  • 다양한 에디터를 사용하여 C++ 문법에 맞게 논리적으로 작성된 프로그램을 원시 파일 또는 소스 파일이라고 한다.
  • C++을 통해 작성된 소스 파일의 확장자는 대부분 .cpp가 된다.


2) 선행처리기에 의한 선행처리

  • 선행처리란 소스 파일 중에서도 #(선행처리 문자)로 시작하는 선행처리 지시문의 처리 작업을 의미한다.
  • 이러한 선행처리 작업은 선행처리기에 의해 처리된다.
  • 선행처리기는 코드를 생성하는 것이 아닌, 컴파일하기 전 컴파일러가 작업하기 좋도록 소스를 재구성해 주는 역할만을 한다.


3) 컴파일러에 의한 컴파일

  • 컴퓨터는 01로 이루어진 2진수로 작성된 기계어만을 이해할 수 있다.
  • 소스 파일은 개발자에 의해 C++ 언어로 작성되기 때문에 컴퓨터가 그것을 바로 이해할 수는 없다.
  • 따라서 소스 파일을 컴퓨터가 알아볼 수 있는 기계어로 변환시켜야 하는데, 그 작업을 컴파일(Compile)이라고 한다.
  • 컴파일은 C/C++ 컴파일러에 의해 수행되며, 컴파일이 끝나 기계어로 변환된 파일을 오브젝트 파일이라고 한다.
  • 이러한 오브젝트 파일의 확장자는 .o.obj가 된다.


4) 링커에 의한 링크

  • 컴파일러에 의해 생성된 오브젝트 파일은 OS와의 인터페이스를 담당하는 시동 코드(Start-up Code)를 가지고 있지 않다.
  • 또한, 대부분의 C++ 프로그램에서 사용하는 표준 라이브러리 파일도 가지고 있지 않다.
  • 하나 이상의 오브젝트 파일과 라이브러리 파일, 시동 코드 등을 합쳐 하나의 파일로 만드는 작업을 링크(Link)라고 한다.
  • 링크는 링커에 의해 수행되며, 링크가 끝나면 하나의 새로운 실행 파일이나 라이브러리 파일이 생성된다.
  • 이처럼 여러 개의 소스 파일을 작성하여 최종적으로 링크를 통해 하나의 실행 파일로 만드는 것을 분할 컴파일이라고 한다.


5) 실행 파일의 생성

  • 소스 파일은 선행처리기, 컴파일러 그리고 링커에 의해 위와 같은 과정을 거쳐 실행 파일로 변환된다.
  • 최근 사용되는 개발 툴은 대부분 선행처리기, 컴파일러, 링커를 모두 내장하고 있으므로 소스 파일에서 한 번에 실행 파일을 생성할 수 있다.
  • 이렇게 생성된 실행 파일의 확장자는 .exe가 된다.


3. C++ 프로그램

1) 간단한 C++ 프로그램

  • 간단한 C++ 프로그램의 기본 구조는 다음과 같다.


#include 문
#define 문

int main()
{
    명령문;
    return ;
}
#include <iostream>
#define TEXT "Welcome to C++ Programming!!"

int main() {
    std::cout << TEXT;

    return 0;
}

// Welcome to C++ Programming!!


2) main() 함수

  • C++ 프로그램은 가장 먼저 main() 함수를 찾고, 그곳에서부터 실행을 시작한다.
  • 따라서 모든 C++ 프로그램은 반드시 하나의 main() 함수를 가지고 있어야 한다.
  • 만약 main() 함수를 발견하지 못하면 C++ 컴파일러는 오류를 발생시킬 것이다.


3) 명령문

  • C++ 프로그램의 동작을 명시하고, 이러한 동작을 컴퓨터에 알려주는 데 사용되는 문장을 명령문이라고 한다.
  • 이러한 C++의 모든 명령문은 반드시 ;(세미콜론)으로 끝나야 한다.


std::cout << "C++ 프로그래밍";  // 정상적으로 출력됨
std::cout << "C++ 프로그래밍"   // 오류가 발생함


4) 반환문

  • 반환문은 함수의 종료를 의미하며, 함수를 호출한 곳으로 결괏값을 반환하는 역할을 한다.
  • 특히 main() 함수가 반환되면, 프로그램 전체가 종료된다.


5) 선행처리문

  • #include 문과 #define 문은 모두 선행처리기에 의해 처리되는 선행처리문이다.
  • #include 문은 외부에 선언된 함수나 상수 등을 사용하기 위해서 헤더 파일의 내용을 현재 파일에 포함할 때 사용한다.
  • C에서는 헤더 파일에 .h 확장자를 사용했지만, C++에서는 헤더 파일의 확장자를 사용하지 않기로 한다.
  • 따라서 기존 C 헤더 파일의 이름 앞에 c를 추가하여 C++ 스타일의 헤더 파일로 변환하기도 한다.


#include <math.h>  // C에서는 이 스타일만 허용됨
#include <cmath>   // C++에서는 이 스타일뿐만 아니라 위의 스타일도 사용할 수 있음


  • #define 문은 함수나 상수를 단순화해 주는 매크로를 정의할 때 사용한다.


6) 네임스페이스

  • 네임스페이스란 이름이 기억되는 영역을 뜻하며, 이름이 소속된 공간을 의미한다.
  • 네임스페이스는 C++ 프로그램을 작성할 때 발생하는 이름에 대한 충돌을 방지해 주는 방법을 제공한다.
  • 이러한 네임스페이스는 C에는 없는 C++만의 새로운 기능이다.


  • C++ 프로그램의 표준 구성 요소인 클래스, 함수, 변수 등은 std라는 네임스페이스에 저장되어 있다.
  • 따라서 C++ 프로그램에서 표준 헤더 파일인 iostream 내의 정의를 사용하려면 다음과 같이 사용해야 한다.


#include <iostream>
#define TEXT "Welcome to C++ Programming!!"

int main() {
    std::cout << TEXT;
    return 0;
}


  • 위의 코드처럼 std라는 네임스페이스에 있는 정의를 사용하려면, std:: 접두어를 붙여 해당 정의가 std라는 네임스페이스에 있다는 것을 컴파일러에 알려줘야 한다.


  • 이러한 네임스페이스에 속한 정의를 간단하게 사용하려면 다음과 같은 명령문을 추가하면 된다.


using namespace std;  // std라는 네임스페이스에 속한 정의들은 네임스페이스 이름을 붙이지 않아도 사용할 수 있음


  • 다음은 위의 코드와 정확히 같은 동작을 수행한다.


#include <iostream>
#define TEXT "Welcome to C++ Programming!!"
using namespace std;

int main() {
    cout << TEXT;
    return 0;
}


7) 주석

  • 주석이란 코드에 대한 이해를 돕는 설명을 적거나 디버깅을 위해 작성하는 일종의 메모이다.
  • C++ 컴파일러는 주석은 무시하고 컴파일하므로, 실행 파일에서는 이러한 주석을 확인할 수 없다.


  • C++에서 주석을 작성하는 문법은 다음과 같다.


// C++ 한 줄 주석


  • C++은 한 줄 주석뿐만 아니라, /*로 시작해서 */로 끝나는 C 스타일의 여러 줄 주석도 사용할 수 있다.


  • 다음과 같이 여러 줄 주석 안에 또 다른 한 줄 주석을 중첩해서 삽입할 수 있다.


/* 여러 줄
    // 이렇게 두 줄 주석 안에 또 다른 한 줄 주석을 삽입할 수 있습니다.
주석입니다. */


  • 위의 코드처럼 C++에서는 여러 줄 주석 안에 또 다른 한 줄 주석을 삽입할 수 있다.
  • 하지만 다음과 같이 여러 줄 주석 안에 또 다른 여러 줄 주석은 중첩해서 삽입할 수는 없다.


 /* 여러 줄
②     /* 또 다른 여러 줄 주석입니다. */
 주석입니다. */


  • 위의 코드처럼 여러 줄 주석 안에 또 다른 여러 줄 주석을 삽입하면, ②번 라인에서 삽입한 */(주석의 종료 기호)를 ①번 라인에서 시작한 첫 번째 주석이 자신의 */로 잘못 인식하게 된다.
  • 따라서 ③번 라인은 주석으로 인식되지 못하고, 컴파일 시 오류가 발생하게 된다.
  • 그러므로 C++에서 여러 줄 주석은 절대로 중첩해서 사용해서는 안 된다.


4. iostream 헤더 파일

1) C++ 표준 입출력 클래스

  • 사용자가 프로그램과 대화하기 위해서는 사용자와 프로그램 사이의 입출력을 담당하는 수단이 필요하다.
  • C++의 모든 것은 객체로 표현되므로, 입출력을 담당하는 수단 또한 C의 함수와는 달리 모두 객체이다.
  • C의 printf() 함수나 scanf() 함수처럼 C++에서도 iostream 헤더 파일에 표준 입출력 클래스를 정의하고 있다.
  • C++에서는 cout 객체로 출력 작업을, cin 객체로 입력 작업을 수행하고 있다.
  • 또한, C++에서는 기존의 C 스타일처럼 printf() 함수나 scanf() 함수로도 입출력 작업을 수행할 수 있다.


2) cout 객체

  • cout 객체는 다양한 데이터를 출력하는 데 사용되는 C++에서 미리 정의된 출력 스트림을 나타내는 객체이다.


  • cout 객체를 사용하는 문법은 다음과 같다.


std::cout << 출력할데이터;


  • <<(삽입 연산자)는 오른쪽에 위치한 출력할 데이터를 출력 스트림에 삽입한다.
  • 이렇게 출력 스트림에 삽입된 데이터는 스트림을 통해 출력 장치로 전달되어 출력된다.


cout << "C++ 수업에 오신 것을 환영합니다!";

// C++ 수업에 오신 것을 환영합니다!


<<(삽입 연산자)

  • 위의 <<가 C의 <<(왼쪽 시프트 연산자)와 같은 모양이다.
  • 이것은 C++의 연산자 오버로딩을 활용한 것이다.


3) cin 객체

  • cin 객체는 다양한 데이터를 입력받는 데 사용되는 C++에서 미리 정의된 입력 스트림을 나타내는 객체이다.


  • cin 객체를 사용하는 문법은 다음과 같다.


std::cin >> 저장할변수;


  • >>(추출 연산자)를 통해 사용자가 입력한 데이터를 입력 스트림에서 추출하여, 오른쪽에 위치한 변수에 저장한다.
  • 이때 cin 객체는 자동으로 사용자가 입력한 데이터를 오른쪽에 위치한 변수의 타입과 동일하게 변환시켜 준다.


#include <iostream>
using namespace std;

int main() {
    int age;

    cout << "여러분의 나이를 입력해 주세요: ";
    cin >> age;

    cout << "여러분의 나이는 " << age << "살입니다." << endl;

    return 0;
}

// 여러분의 나이를 입력해 주세요: 15 (입력)
// 여러분의 나이는 15살입니다.


  • 위의 코드에서 입력한 데이터는 자동으로 정수를 저장할 때 사용하는 타입으로 변환될 것이다.
  • 만약에 문자열을 입력하면 cin 객체는 변수 age에 숫자가 아니라는 의미인 0을 전달할 것이다.


4) C 표준 입출력 함수와의 차이점

  • C 표준 입출력 함수인 printf() 함수나 scanf() 함수와 C++ 표준 입출력 객체와의 차이점은 다음과 같다.


1] <<>>가 데이터의 흐름을 나타내므로 좀 더 직관적이다.

2] C++ 표준 입출력 객체는 입출력 데이터의 타입을 자동으로 변환시켜주므로 더욱 편리하고 안전하다.


References