C++ 프로그램 기본 구성

  • 주석: C++에서는 프로그램 코드에 대한 설명이나 메모를 추가하기 위해 주석을 사용한다. 전통적인 C 스타일의 블록 주석(/* ... */)뿐만 아니라 한 줄 주석(//)도 지원한다. 한 줄 주석은 // 이후의 모든 내용을 해당 줄에서 무시하여 실행에 영향을 주지 않는다.
  • 전처리기 지시어: 소스 코드 상단에는 전처리기(preprocessor)에게 헤더 파일을 포함하라는 지시를 한다. 예를 들어 #include <iostream>를 사용하여 표준 입출력 기능을 제공하는 iostream 헤더 파일을 프로그램에 포함시킨다. 이 헤더에는 콘솔 입출력에 필요한 cout 객체와 endl 조작자 등이 선언되어 있다.
  • 네임스페이스 선언: 표준 이름공간(namespace)std를 전역 범위에서 사용하겠다고 선언하는 구문이 using namespace std;이다. 이 줄을 추가하면 이후 코드에서 std::를 생략하고 표준 라이브러리의 구성 요소를 바로 사용할 수 있다. 이 선언이 없는 경우에는 std::cout, std::endl처럼 범위 지정 연산자(scope resolution operator) ::를 이용해 해당 이름이 속한 이름공간을 명시해야 한다.
  • 메인 함수: 모든 C++ 프로그램에는 프로그램의 시작점(entry point)인 main 함수를 정의해야 한다. 일반적으로 int main() { ... } 형태로 작성하며, 중괄호 {} 내부에 프로그램 실행에 필요한 명령문들을 순서대로 기술한다. main 함수는 정수형 값을 반환하도록 선언되며, 함수의 마지막에 return 0; 문을 넣어 프로그램이 정상적으로 종료되었음을 운영체제에 알린다.[[1]]

[[1]]: 0은 관례적으로 정상 종료를 의미한다.

#include <iostream>    // 표준 입출력 헤더 파일 포함
using namespace std;   // 표준 이름공간 사용 선언

int main() {
    cout << "Hello, World!" << endl;    // 화면에 "Hello, World!" 출력 후 줄바꿈
    system("pause");          // 프로그램 일시 정지 (Windows 전용)
    return 0;                 // 0을 반환하며 프로그램 정상 종료
}

C++ Hello, World! 출력 예시

Hello World!

실행 결과

💡
C/C++에서는 세미콜론(;)을 이용하여 한 줄에 여러 명령문을 작성할 수 있다. 예를 들어 cout << endl; system("pause"); return 0;처럼 세 개의 명령문을 한 줄에 구분하여 넣어도 유효한 문법이다. 또한 Windows 환경에서는 system("pause") 명령을 사용하면 프로그램 실행 후 콘솔 창이 바로 닫히지 않도록 일시 정지할 수 있다.

표준 라이브러리

C++는 다양한 기능을 제공하는 표준 라이브러리(standard library)를 갖추고 있다.

  • C 표준 라이브러리: <stdio.h>, <stdlib.h>, <string.h>, <math.h> 등 C 언어에서 사용하던 표준 라이브러리 헤더
  • C++에서 제공하는 C 라이브러리: <cstdio>, <cstdlib>, <cstring>, <cmath> 등 기존 C 라이브러리 헤더의 C++ 대응 버전
  • 입출력 및 문자열 관련 라이브러리: <iostream>, <string>, <fstream> 등 스트림 입출력과 문자열 처리를 위한 헤더
  • STL(Standard Template Library): <vector>, <list>, <algorithm> 등 템플릿 기반의 표준 자료구조 및 알고리즘 라이브러리

C++에서는 표준 라이브러리 헤더를 포함할 때 헤더 이름에 .h 확장자를 사용하지 않는 것이 원칙이다. C 언어의 <stdio.h> 헤더는 C++에서는 <cstdio> 형태로 포함하는 것이 권장된다.

물론 <stdio.h>처럼 C 표준 헤더를 그대로 포함하는 것도 동작은 하지만, 새 코드에서는 대응되는 C++ 형식의 헤더를 사용하는 것이 좋다. iostream처럼 C++ 전용으로 제공되는 헤더에 과거에 .h를 붙여 사용하던 방식(예: <iostream.h>)은 현재 표준이 아니므로 사용하지 말아야 한다.

system() 함수와 cin.get() 기능

운영체제의 기능을 호출하거나 프로그램의 실행을 일시 정지시키기 위해 system() 함수cin.get() 함수를 사용할 수 있다.

system() 함수

system() 함수는 C 표준 라이브러리에서 제공되는 함수로, 인자로 전달된 문자열을 운영체제의 명령어로 실행한다.

이를 통해 프로그램에서 운영체제의 각종 명령을 직접 호출할 수 있다. Windows 환경에서 system("pause")를 호출하면 DOS 명령어 pause를 실행하여 콘솔 프로그램을 일시 정지시킨다.[[2]]

[[2]]: macOS나 Linux에는 pause라는 명령어가 없기 때문에 오류가 발생한다.

  • system("pause") – DOS의 pause 명령을 실행하여 프로그램을 일시 정지
  • system("dir") – 현재 디렉터리의 파일 목록을 표시하는 DOS dir 명령 실행
  • system("cls") – 콘솔 화면을 지우는 DOS cls 명령 실행

이처럼 system(명령어) 형식으로 사용하면 전달한 문자열을 OS 콘솔에 넘겨 해당 명령을 수행한다. 다만 system() 함수는 권장되지 않는다. 이 함수는 운영체제에 종속적인 기능이므로 코드의 이식성을 떨어뜨릴 수 있고, 보안 측면에서도 취약점이 생길 가능성이 크다.

실제로 수업은 윈도우 환경 기반이라 Dev-C++를 사용하여 코드를 작성하는데, 나는 맥이라 CLion을 설치했고 수업에서 준 첫 코드에 system("pause")가 있어서 오류가 발생했었다. 그래서 그냥 system("pause")를 지우고 아래 코드로 대체해서 쓴다.

std::cout << "실행 결과를 확인했습니다. 계속하려면 엔터 키를 누르세요...\n";
std::cin.ignore(); return 0;  //system("pause") on Windows.

system("pause") 대체 코드

cin.get() 함수

표준 입력 스트림 cin의 멤버 함수인 cin.get()은 사용자의 입력을 한 문자 읽을 때까지 대기하는 기능을 제공한다. 인자 없이 cin.get()을 호출하면 키보드로부터 문자 하나 (엔터 키 입력 포함)를 받을 때까지 프로그램 실행을 멈추므로, 콘솔 창이 바로 닫히지 않도록 일시 정지하는 용도로 활용할 수 있다.

cout 표준 출력

C++에서는 cout 객체를 사용하여 콘솔에 데이터를 출력한다. cout은 표준 출력(standard output) 스트림으로 정의되어 있으며, 기본적으로 프로그램의 표준 출력 장치인 콘솔 창(모니터 화면)에 텍스트를 출력한다.

출력 연산에는 삽입 연산자 <<를 사용하며, 연산자 오른쪽에 출력할 데이터를 지정하면 해당 값이 출력된다. 여러 값을 연속으로 출력하고자 할 때는 cout << 값1 << 값2 << 값3;처럼 << 연산자를 이어서 사용하면 된다.

프로그램 실행 중 줄바꿈을 포함하고 싶다면 출력할 문자열에 개행 문자 '\n'을 넣거나 endl 조작자를 사용할 수 있다. endl을 출력하면 개행 문자를 출력하는 효과가 발생하며, 결과적으로 줄을 바꾸게 된다.

예를 들어 cout << "Hello" << endl;cout << "Hello\n";과 동일하게 "Hello"를 출력한 뒤 줄을 변경한다. 일반적으로 둘 다 동일한 새 줄 삽입 기능을 하지만, endl은 출력 버퍼를 비우는 부가 동작까지 수행한다.

식별자와 키워드

식별자 (Identifier)

식별자는 프로그래머가 임의로 정의하는 이름을 말한다. 변수 이름, 함수 이름, 클래스 이름 등이 모두 식별자의 예이며, 식별자를 통해 프로그램의 다양한 요소를 식별하고 참조할 수 있다.

C++에서 식별자를 만들 때는 다음과 같은 규칙을 따라야 한다:

  • 식별자는 영문자(알파벳), 숫자(0-9), 그리고 밑줄 문자(_)로 구성
  • 대문자와 소문자를 서로 구분하며, 동일 철자의 대소문자는 다른 식별자로 취급
  • 식별자의 첫 글자는 영문자 또는 밑줄로 시작해야 하고, 숫자로 시작할 수 없다. ( Example1은 유효하지만 1Example은 허용되지 않음)

이러한 규칙을 벗어난 이름(공백이나 특수 기호를 포함한 이름 등)은 식별자로 사용할 수 없으며, 컴파일 시 오류가 발생한다.

키워드 (Keyword)

키워드(keyword) 또는 예약어(reserved word)는 C++ 언어에서 이미 특정한 기능을 위해 예약된 단어들을 말한다. 번역기(컴파일러)가 미리 인식하고 있는 단어이기 때문에 프로그래머가 임의의 식별자로 사용할 수 없다.

예를 들어 if, switch, for, while, int 등은 모두 C++의 키워드이며, 변수명이나 함수명 등으로 사용할 수 없다. 키워드를 식별자로 사용하면 문법적으로 의미가 혼동되므로 언어 차원에서 이를 금지하고 있다.

프로그램 실행에 이용되는 메모리 영역

C++ 프로그램이 실행되면 운영체제는 해당 프로세스를 위해 주기억장치에 여러 메모리 영역을 할당한다.

주요 메모리 영역은 다음 네 가지로 구분된다:

  • 코드 영역(Code segment): 실행할 프로그램의 기계어 코드가 저장되는 영역이다. 컴파일된 프로그램 명령어들이 이 영역에 적재되어 CPU에 의해 실행된다.
  • 데이터 영역(Data segment): 전역 변수와 정적(static) 변수, 그리고 프로그램에 내장된 리터럴 상수(예: 문자열 리터럴)를 저장하는 영역이다. 프로그램 시작과 함께 할당되며, 종료 시까지 메모리가 유지된다.
  • 힙 영역(Heap segment): 프로그래밍 중 동적 메모리(dynamic memory) 할당을 위해 사용되는 영역이다. new 연산자를 통해 할당한 메모리가 이 영역에 확보되며, 명시적으로 해제(delete)하기 전까지 유지된다.
  • 스택 영역(Stack segment): 함수가 호출될 때 생성되는 지역 변수(local variable)나 함수 매개변수 등이 저장되는 영역이다. 함수 호출 시 스택에 메모리가 할당되고, 함수가 종료되면 해당 스택 영역이 자동으로 반환되어 메모리가 해제된다. 스택은 LIFO(Last-In First-Out) 구조로, 함수 호출과 복귀에 따라 메모리가 관리된다.

이름공간 (namespace)

여러 개의 프로그램 요소가 동일한 이름을 가질 때 충돌을 방지하기 위해 C++에는 네임스페이스라는 개념이 도입되었다. 네임스페이스를 사용하면 동일한 이름의 식별자들을 별개의 범위로 구분하여 관리할 수 있다.

네임스페이스가 필요한 이유를 쉽게 이해해보자. (스파이더맨: 노 웨이 홈)

🎬
스파이더맨: 노 웨이 홈 에서 네드가 연구실에서 "피터!"라고 부르자, 서로 다른 세계에서 온 세 명의 피터 파커가 동시에 돌아보며 "응?" 하고 반응하는 장면이 있다. 이때 네드는 당황하지만, 네임스페이스 개념을 적용해서 "아니, 우리 세계의 피터!"라고 더 구체적으로 지칭했다면 쉽게 풀어나갈 수 있을 것이다.
프로그래밍에서도 동일한 이름의 함수나 변수가 여러 곳에서 사용될 때, 네임스페이스를 활용해 구체적으로 구분하면 충돌이나 혼동 없이 명확히 사용할 수 있다.

C++ 표준 라이브러리의 모든 함수와 객체는 std라는 이름공간에 속해 있다. 따라서 표준 라이브러리 기능을 사용할 때는 항상 std:: 접두사를 붙이거나, 앞서 설명한 using namespace std; 선언을 통해 해당 이름공간을 사용한다고 명시해야 한다.

예를 들어 표준 출력 객체 cout의 실제 이름은 std::cout이고, 문자열 클래스 string의 실제 이름은 std::string이다. 이처럼 이름공간을 적절히 활용하면 동일한 이름의 함수나 변수가 여러 라이브러리나 모듈에 존재하더라도 네임 충돌 없이 사용할 수 있다.

💻 이 글은 C++ 프로그래밍 시리즈의 일부입니다.

다음글: 데이터 타입형