> For the complete documentation index, see [llms.txt](https://byulseop-til.gitbook.io/sinheeseop_til/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://byulseop-til.gitbook.io/sinheeseop_til/c++/101/cpp_basic_syntax.md).

# BasicSyntax

아래는 C++의 기본 문법 요소들이 왜 생겼는지에 대한 배경, 그 동작 원리, 그리고 실제 사용 예시를 함께 설명한 내용입니다. 이를 통해 단순한 사용법을 넘어서 각 요소의 목적과 의미를 이해할 수 있습니다.

***

### 1. 전처리기 지시문 (Preprocessor Directives)

#### 왜 생겼는가?

* **역사적 배경**: C 언어 시절부터 사용되어 왔으며, 컴파일 전에 코드를 조작하여 공통 선언이나 조건부 컴파일을 지원하기 위해 도입되었습니다.
* **필요성**:
  * 코드 재사용 및 모듈화 (객체지향)
  * 조건에 따른 코드 컴파일(예: 디버깅 모드, 플랫폼별 코드 분리)
* 자바와의 차이점
  * C++의 `#include`는 전처리기 단계에서 해당 파일의 내용을 소스 코드에 그대로 삽입합니다.
  * Java의 `import`는 단순히 패키지 내의 클래스를 참조할 수 있도록 이름을 선언하는 역할을 합니다. (실제로 파일의 내용을 가져오지는 않습니다.)

#### 사용 예시 및 설명

```cpp
#include <iostream>  // iostream 헤더를 포함해 입출력 관련 기능을 사용 가능하게 함
#define PI 3.14159265  // 상수 PI를 정의 (컴파일 시점에 텍스트 치환)

int main() {
    // 컴파일러는 전처리 단계에서 #include와 #define을 먼저 처리합니다.
    std::cout << "PI: " << PI << std::endl;  // 치환된 PI 값을 출력
    return 0;
}
```

* **예시 설명**:
  * `#include <iostream>`은 컴파일 전에 해당 파일의 내용을 삽입하여, `std::cout` 등 입출력 객체를 사용할 수 있도록 해줍니다.
  * `#define PI 3.14159265`는 코드 내에 `PI`가 등장하면 모두 `3.14159265`로 치환되며, 이로써 코드의 재사용성과 가독성을 높입니다.

### 2. 네임스페이스 (Namespaces)

#### 왜 생겼는가?

* **역사적 배경**: 초기 C에서는 모든 함수와 변수가 전역 공간에 존재하여, 이름 충돌이 빈번했습니다.
* **필요성**:
  * 이름 충돌 방지 및 모듈 간 구분
  * 코드 조직 및 가독성 향상

#### 사용 예시 및 설명

```cpp
#include <iostream>

// std 네임스페이스에 정의된 기능들을 사용하기 위해 지정
using namespace std;

int main() {
    // std:: 없이 cout과 endl을 바로 사용 가능 (네임스페이스 덕분)
    cout << "Hello, Namespaces!" << endl;
    return 0;
}

```

* **예시 설명**:
  * `using namespace std;`를 사용하면 `std::cout`, `std::endl`을 매번 쓰지 않아도 됩니다.
  * 이는 여러 라이브러리에서 같은 이름을 사용하더라도, 각 네임스페이스로 구분하여 이름 충돌을 방지하는 역할을 합니다.

### 3. main 함수

#### 왜 생겼는가?

* **역사적 배경**: 운영체제는 프로그램을 실행할 때 명확한 진입점(entry point)이 필요하며, C/C++ 표준은 이를 `main` 함수로 규정합니다.
* **필요성**:
  * 프로그램 실행 시작점
  * 운영체제에 종료 상태(리턴값)를 전달

#### 사용 예시 및 설명

```cpp
#include <iostream>
using namespace std;

int main() {
    // 프로그램의 시작점입니다.
    cout << "Program started!" << endl;

    // 프로그램 실행 과정
    // (예: 초기화, 입력 처리, 연산 수행 등)

    // 0을 리턴함으로써 정상 종료를 운영체제에 알림
    return 0;
}

```

* **예시 설명**:
  * 모든 C++ 프로그램은 `main` 함수에서 시작하며, `return 0;`은 프로그램이 정상적으로 종료되었음을 운영체제에 전달합니다.
  * `main` 함수는 프로그램의 핵심 흐름을 제어하며, 인자 전달(`int argc, char* argv[]`)을 통해 외부 입력을 받을 수도 있습니다.

### 4. 기본 입출력 (Input/Output)

#### 왜 생겼는가?

* **역사적 배경**: C의 입출력 함수(예: `printf`, `scanf`)보다 더 안전하고, 타입에 독립적인 입출력을 위해 C++는 스트림 기반의 입출력 시스템을 도입했습니다.
* **필요성**:
  * 하드웨어 독립적이며, 일관된 입출력 인터페이스 제공
  * 버퍼링을 통한 성능 최적화
  * 연산자 오버로딩을 통해 다양한 타입의 데이터를 쉽게 처리

#### 사용 예시 및 설명

```cpp
#include <iostream>
using namespace std;

int main() {
    // 출력 스트림 사용: std::cout를 통해 문자열과 변수를 출력
    cout << "Enter your age: ";

    // 입력 스트림 사용: std::cin를 통해 사용자로부터 데이터를 입력받음
    int age;
    cin >> age;

    // 사용자에게 입력받은 데이터를 다시 출력
    cout << "Your age is: " << age << endl;

    return 0;
}

```

* **예시 설명**:
  * `cout <<` 연산자를 통해 데이터를 출력하고, `cin >>` 연산자를 통해 데이터를 입력받습니다.
  * `endl`은 줄바꿈을 하며 출력 버퍼를 비워, 출력이 즉시 화면에 반영되도록 돕습니다.

### 5. 변수 선언 및 데이터 타입

#### 왜 생겼는가?

* **역사적 배경**: C++는 C의 성능과 메모리 제어 능력을 유지하면서, 코드 안정성과 가독성을 높이기 위해 정적 타입 시스템을 채택했습니다.
* **필요성**:
  * 컴파일 시 타입 검사를 통해 오류를 미리 예방
  * 메모리 사용과 최적화 측면에서 효율적인 코드를 생성
  * 변수의 용도와 범위를 명확하게 하기 위해

#### 사용 예시 및 설명

```cpp
#include <iostream>
using namespace std;

int main() {
    // 정수형 변수 선언 및 초기화: 메모리에서 4바이트 공간 확보
    int count = 10;

    // 실수형 변수 선언: double은 더 정밀한 실수를 표현
    double price = 99.99;

    // 문자형 변수 선언: 단일 문자를 저장
    char grade = 'A';

    // 불린형 변수 선언: true 혹은 false 값을 가짐
    bool isActive = true;

    // 변수 값 출력
    cout << "Count: " << count << endl;
    cout << "Price: " << price << endl;
    cout << "Grade: " << grade << endl;
    cout << "Active: " << isActive << endl;

    return 0;
}

```

* **예시 설명**:
  * 각 변수는 선언 시 데이터 타입을 명시하여, 해당 변수에 저장될 데이터의 크기와 메모리 공간을 컴파일러가 결정합니다.
  * 정적 타입 시스템 덕분에, 타입이 잘못 사용되면 컴파일 시점에 오류를 발생시켜 런타임 오류를 예방합니다.

### 종합 정리

* **전처리기 지시문**:

  코드의 재사용과 조건부 컴파일을 위해, 컴파일 전에 헤더 파일과 매크로 정의를 처리합니다.

  **예시**: `#include <iostream>`, `#define PI 3.14159265`
* **네임스페이스**:

  이름 충돌을 방지하고 모듈화를 지원하기 위해 도입되었습니다.

  **예시**: `using namespace std;`
* **main 함수**:

  프로그램의 진입점으로, 운영체제와의 연동 및 종료 상태 전달을 위해 사용됩니다.

  **예시**: `int main() { ... return 0; }`
* **기본 입출력**:

  스트림 기반 입출력을 통해, 다양한 데이터 타입을 일관되게 처리하며, 버퍼링과 하드웨어 독립성을 제공합니다.

  **예시**: `cout << "Hello" << endl;`, `cin >> age;`
* **변수 선언 및 데이터 타입**:

  정적 타입 시스템을 활용해 메모리 할당, 타입 안전성, 코드 가독성을 높입니다.

  **예시**: `int count = 10;`, `double price = 99.99;`
