CodeGym /행동 /C++ SELF /컴파일러와 주석

컴파일러와 주석

C++ SELF
레벨 1, 레슨 5
사용 가능

1. 컴파일러 소개

컴퓨터는 인간의 언어를 이해하지 못합니다. 컴퓨터는 심지어 프로그래밍 언어조차 직접 이해하지 못합니다. 컴퓨터가 이해하는 것은 오직 기계어로 작성된 프로그램뿐—0과 1로 이루어진 코드입니다. 반면 사람은 단어와 아이디어로 사고하기 때문에, 오직 0과 1만으로 전체 프로그램을 만드는 것은 매우 어렵습니다.

00100100는 십진수 36 또는 기호 $로 해석됩니다

그래서 C++ 같은 프로그래밍 언어가 등장했습니다. 이 언어들은 일종의 "통역사"가 되어 프로그래머가 이해하기 쉬운 언어로 명령을 작성하면, 그것을 기계가 이해할 수 있는 형태로 바꿔줍니다.

하지만 한 가지 문제가 있습니다. 컴퓨터는 여전히 C++을 직접 이해하지 못합니다! C++ 코드가 들어있는 파일을 그대로 주면, 컴퓨터는 어깨를 으쓱하고 아무 일도 하지 않습니다. 이런 상황을 위해 컴파일러가 존재합니다.

컴파일러란 무엇인가?

컴파일러는 코드를 컴파일하는 특별한 프로그램입니다: C++ 코드를 컴퓨터가 이해할 수 있는 코드로 번역합니다. 컴파일러는 C++로 작성된 텍스트를 읽고 분석하여 오류를 검사하고 기계어(보통 실행 파일 형태)로 변환합니다.

  • C++ 언어로 작성된 프로그램
  • 컴파일러
  • 기계어로 이루어진 프로그램
C++의 컴파일 단계

컴파일러를 엄격한 교사에 비유할 수 있습니다. 이 교사는:

  • 구문을 주의 깊게 검사합니다 (실수를 하지 않았나요?),
  • 규칙을 지키게 합니다 (예: 올바른 변수 이름, 세미콜론, 괄호 등),
  • 그리고 그다음에야 컴퓨터와의 면접에 통과시킵니다!

컴파일러는 더 똑똑해졌습니다

요즘 C++ 컴파일러는 단순히 번역만 하지 않고, 코드를 최적화하거나 오류를 알려주고 더 나은 코딩 방법을 제안하기도 합니다(경고—warnings 형태로 제공). 그 밖에도 많은 기능을 가지고 있습니다.

또한 큰 프로젝트를 올바르게 빌드하기 위해 컴파일은 보통 “한 번의 마법 같은 단계”로 끝나지 않고, 적어도 여러 단계로 이루어집니다:

  • 먼저 전처리기가 #include 같은 지시문을 처리합니다.
  • 그다음 컴파일러가 C++ 코드를 오브젝트 코드(부분적으로 만들어진 프로그램 조각)로 변환합니다.
  • 마지막으로 링커(컴포너)가 이 조각들과 연결된 라이브러리를 합쳐 하나의 실행 파일로 만듭니다.

만약 좋은 CPU와 최적화 옵션을 사용하면, 컴파일러는 플랫폼의 특성과 빌드 설정을 고려해 기계어를 생성할 수 있습니다. 하지만 핵심 아이디어는 단순합니다: C++는 보통 바로 기계어로 컴파일되고, 그 생성된 실행 파일이 나중에 실행됩니다.

       flowchart TD
    SRC["소스 코드 .cpp 파일들"]:::source

    PP["전처리기 #include 와 #define 처리"]:::stage
    CC["컴파일러 C++ → 오브젝트 코드로 변환 오류를 찾고 warnings 제공"]:::stage
    LN["링커 오브젝트 코드 연결 + 라이브러리 포함"]:::stage

    EXE["실행 파일 .exe"]:::artifact

    RUN(["▶ 실행 생성된 기계어는 바로 실행됩니다"]):::run

    LIB["라이브러리"]:::lib
    DEV["개발자가 오류를 수정함"]:::dev

    SRC --> PP --> CC --> LN --> EXE --> RUN
    CC -.->|"⚠️ warnings & 오류"| DEV
    LIB --> LN

    classDef source fill:#f59e0b,color:#1c1917,stroke:none
    classDef stage fill:#3b82f6,color:#fff,stroke:#1d4ed8,stroke-width:2px
    classDef artifact fill:#8b5cf6,color:#fff,stroke:#6d28d9,stroke-width:2px
    classDef lib fill:#64748b,color:#fff,stroke:none
    classDef run fill:#22c55e,color:#fff,stroke:none
    classDef dev fill:#fde68a,color:#1c1917,stroke:#f59e0b,stroke-width:1px
   
전체 아이디어를 이해하기 위한 단순화된 도식입니다.

2. 컴파일 오류

코드의 속도나 최적화는 지금 당장은 그다지 중요하지 않습니다. 하지만 중요한 것은 컴파일러가 프로그램의 오류를 검사한다는 점입니다. 컴파일러는 코드의 올바름을 검사하고, 작은 오류라도 발견하면 더 이상 진행시키지 않습니다.

오류 예시:

문자열만 저장할 수 있는 변수에 숫자를 할당하려고 시도한 경우입니다.

#include <string>

int main() {
    std::string userName = 42; // 어이쿠! 이렇게 할 수 없습니다.
}

컴파일러는 곧바로 타입이 맞지 않는다고 오류를 내며(메시지 표현은 컴파일러마다 다름), 대략 이렇게 말할 것입니다: “적절한 변환이 없어 int에서 std::string으로 변환할 수 없습니다”.

또 다른 예는 std::cout의 이름을 잘못 쓴 경우입니다:

#include <iostream>

int main() {
    std::coutt << "안녕하세요!\n"; // 이름이 잘못되었습니다
}

컴파일러는 보통 이렇게 말합니다: “coutt는 std의 멤버가 아닙니다” — 문법을 확인하세요!

오류를 어떻게 읽을까?

대부분의 컴파일러는 코드에서 오류가 발생한 위치를 알려줍니다: 보통 파일, 행 번호, 종종 열 번호까지 표시하며 오류 메시지 텍스트도 제공합니다. 오류를 두려워하지 마세요: 각각의 오류는 여러분의 실력을 키우는 단계입니다.

3. 자주 발생하는 컴파일 오류

expected는 다음을 의미합니다: “여기서 기호 X를 기대했지만 없습니다”. 가장 흔한 경우는 다음과 같습니다:

expected ';' — 세미콜론을 잊음

잘못된 코드:

#include <iostream>

int main() {
    std::cout << "Hello!\n"
    return 0;
}

명령은 ;로 끝나야 합니다. 컴파일러는 return까지 왔지만 여전히 ;를 기다리고 있던 상황입니다. 수정:

std::cout << "Hello!\n";

expected '}' — 블록을 닫지 않음

}를 잊으면 컴파일러는 보통 파일 끝에서 오류를 보고합니다.

int main() {
    std::cout << "Start\n";
    return 0;
// 닫는 } 없음

그냥 블록을 닫아주세요:

}

팁: 들여쓰기를 잘 하면 빠진 괄호를 찾기 쉽습니다.

expected ')' 또는 expected '(' — 괄호 문제

int main( {

정상적인 형태:

int main() {

괄호는 항상 쌍으로 열리고 닫혀야 합니다.

not declared — 이름을 찾을 수 없음

컴파일러는 “이게 무엇인지 모릅니다”라고 말합니다. std::를 잊은 경우가 흔합니다.

cout << "Hi\n";

정상적으로는:

std::cout << "Hi\n";

cout는 네임스페이스 std에 있습니다.

#include <iostream>를 잊음

int main() {
    std::cout << "Hi\n";
}

다음을 추가하세요:

#include <iostream>

#include가 없으면 컴파일러는 std::cout가 무엇인지 모를 수 있습니다.

4. 주석

누가 “내 코드는 주석이 필요 없다, 어차피 이해하기 쉬우니까”라고 주장했던 그 사람의 코드를 읽고 있는 중입니다.

상황을 상상해보세요: 복잡한 프로그램을 작성했습니다. 모든 것이 작동하고 당신은 천재입니다! 하지만 한 달 뒤 그 코드를 열어보면... 아무것도 이해가 되지 않습니다. 여기저기 몇 줄, 이상한 변수명. 머릿속에는 “이건 분명히 누구나 쓸 수는 있지만 나만은 아닐 거야!”라는 생각만 남습니다. 이때 주석이 도움을 줍니다.

주석은 교과서의 여백 메모나 냉장고의 메모와 같습니다("맥주. 마시지 마세요. 아침에!"). 컴파일러는 주석을 무시하고, 사람은 반대로 주석을 봅니다. 주석은 코드의 의미를 설명하고 중요한 부분을 표시하며, 코드를 삭제하지 않고 일시적으로 비활성화할 수도 있게 해줍니다.

중요: 컴파일러는 여러분의 주석 내용을 "이해"하지 않습니다—그저 건너뛰어야 할 텍스트일 뿐입니다.

한 줄 주석

C++에는 한 줄 주석과 여러 줄 주석 두 종류가 있습니다. 한 줄 주석은 두 개의 슬래시 //로 시작해서 그 줄의 끝까지 계속됩니다. 슬래시 뒤의 모든 내용은 주석으로 간주되어 컴파일러에 의해 무시됩니다.

예:

#include <iostream>

int main() {
    std::cout << "안녕, 세계!\n"; // 화면에 인사말을 출력합니다
}

여기서 // 화면에 인사말을 출력합니다는 주석입니다. 코드의 어느 줄이 왜 필요한지 모를 때 이렇게 적어두면 됩니다!

또 다른 예:

int main() {
    int x = 42; // 프로그래머의 나이 값
}

한 줄짜리 주석은 독립된 줄로도 작성할 수 있습니다:

#include <string>

int main() {
    // 사용자 이름 변수 초기화
    std::string userName = "Vasya";
}

마치 대본의 대사처럼: 주석은 행위의 이유를 설명합니다.

여러 줄 주석

만약 설명해야 할 내용이 많다면 어떻게 할까요? 여러 줄 주석을 사용하면 됩니다. 여러 줄 주석은 /*로 시작해서 */로 끝납니다. 이 사이의 모든 내용은 여러 줄에 걸쳐 있어도 컴파일러가 무시합니다.

예:

#include <iostream>

int main() {
    /*
      여기서는 사용자에게 안내 메시지를 출력합니다.
      이름이 없으면 다른 프로그램에서는 "Guest"라고 쓸 수 있습니다.
    */
    std::cout << "이름을 입력하세요:\n";
}

또는 이렇게:

int main() {
    int age = 18; /* 신규 사용자 초기 나이 값
                     입니다 */
}

주의: 다중 주석 안에 또 다른 다중 주석을 중첩시킬 수 없습니다. 컴파일러보다 더 영리하게 굴려고 하지 마세요—작동하지 않습니다.

설명 표:

종류 구문 예
한 줄
// comment
int x = 1; // explanation
여러 줄
/* some multi-line comment */
/* you can explain everything here */

5. 실생활 예시

코드 라인 "비활성화":

일시적으로 어떤 코드 조각을 실행하지 않게 하고 싶을 때가 있습니다. 이런 경우 주석이 유용합니다:

// std::cout << "임시로 필요 없는 텍스트\n";

라인은 남아 있지만 컴파일러는 그것을 “보지” 않습니다.

TODO와 FIXME 표시

프로그래머도 사람이라 가끔 자신에게 이 코드가 아직 완성되지 않았거나 버그가 있음을 알려야 할 때가 있습니다. 보통 이렇게 적습니다:

// TODO: 빈 입력 체크 추가
// FIXME: 이 함수가 합계를 잘못 계산함

많은 편집기와 IDE는 이런 단어들을 강조 표시해 줍니다!

프로그래머들의 농담

물론 때때로 코드에서 아주 흥미로운 주석들을 볼 수 있습니다:

// 나는 이 코드에 책임지지 않습니다. 이 코드는 본의 아니게 작성되었습니다.
// 친애하는, 저는_미래에서_왔습니다! 제발 이 코드를 용서해주세요.
// 만약 제가 이런 걸 또 보게 된다면, 출근할 때 무기를 들고 가야 할지 모르겠습니다.
// 이 조건이 언젠가 충족된다면, 보상으로 전화번호 xxx-xx-xx로 연락해주세요.
// 친애하는 프로그래머:
//
// 이 서브루틴을 "최적화"하고
// 그게 얼마나 큰 실수였는지 깨달았을 때,
// 제발 아래의 카운터를 경고로 증가시켜 주세요
// 다음 사람을 위해:
//
// hours_spent_here = 42
// 이걸 처음 쓸 때는 오직 신과 나만 내가 무엇을 하는지 이해했다.
// 지금은 신만 남아있다
// 가끔은 컴파일러가 내 모든 주석을 무시하는 것 같다고 느낀다
// 나는 내 모든 코드와 노력을 아내 Darlin에게 바칩니다. 
// 그녀는 내가 프로덕션에 들어갈 때 우리 가족과 개를 부양해야 할 것입니다.

네, 주석은 매우 재미있을 수 있습니다. 결국 그것들은 살아 있는 사람들이 씁니다.

1
과제
C++ SELF, 레벨 1, 레슨 5
잠금
사라진 세미콜론
사라진 세미콜론
1
과제
C++ SELF, 레벨 1, 레슨 5
잠금
잃어버린 cout
잃어버린 cout
1
과제
C++ SELF, 레벨 1, 레슨 5
잠금
디버그 비활성화
디버그 비활성화
1
과제
C++ SELF, 레벨 1, 레슨 5
잠금
오류 연쇄
오류 연쇄
1
설문조사/퀴즈
첫 번째 프로그램, 레벨 1, 레슨 5
사용 불가능
첫 번째 프로그램
첫 번째 프로그램
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION