수색…


비고

'Hello World'프로그램은 컴파일러와 라이브러리 존재를 확인하는 데 사용할 수있는 일반적인 예입니다. <iostream> std::cout 과 함께 C ++ 표준 라이브러리를 사용하며 컴파일 할 때 하나의 파일 만 가지므로 컴파일 중에 사용자 오류가 발생할 가능성을 최소화합니다.


C ++ 프로그램을 컴파일하는 프로세스는 컴파일러와 운영 체제에 따라 다릅니다. 컴파일 및 빌드 주제에는 여러 컴파일러에서 서로 다른 플랫폼에서 C ++ 코드를 컴파일하는 방법에 대한 세부 정보가 들어 있습니다.

버전

번역 표준 출시일
C ++ 98 ISO / IEC 14882 : 1998 1998-09-01
C ++ 03 ISO / IEC 14882 : 2003 2003-10-16
C ++ 11 ISO / IEC 14882 : 2011 2011-09-01
C ++ 14 ISO / IEC 14882 : 2014 2014-12-15
C ++ 17 미정 2017-01-01
C ++ 20 미정 2020-01-01

안녕하세요 세계

이 프로그램은 Hello World! 인쇄합니다 Hello World! 표준 출력 스트림 :

#include <iostream>

int main()
{
    std::cout << "Hello World!" << std::endl;
}

그것은 Coliru에 살고보십시오 .

분석

이 코드의 각 부분을 자세히 살펴 보겠습니다.

  • #include <iostream> 은 표준 C ++ 헤더 파일 iostream 의 내용을 포함하는 선행 처리기 지시문 입니다.

    iostream 은 표준 입력 및 출력 스트림의 정의가 들어있는 표준 라이브러리 헤더 파일 입니다. 이러한 정의는 아래에 설명 된 std 네임 스페이스에 포함됩니다.

    표준 입출력 (I / O) 스트림 은 프로그램이 외부 시스템 (일반적으로 터미널)에서 입출력을 얻을 수있는 방법을 제공합니다.

  • int main() { ... }main 이라는 새 함수를 정의합니다. 규칙에 따라 main 기능은 프로그램 실행시 호출됩니다. C ++ 프로그램에는 main 함수가 하나만 있어야하며 항상 int 유형의 숫자를 반환해야합니다.

    여기서 int 는 함수의 반환 형식 이라고합니다. main 함수가 반환하는 값은 종료 코드입니다.

    규칙에 따라 프로그램 종료 코드 0 또는 EXIT_SUCCESS 는 프로그램을 실행하는 시스템에서 성공으로 해석됩니다. 다른 모든 리턴 코드는 오류와 연관됩니다.

    return 문이 없으면 main 함수 (따라서 프로그램 자체)는 기본적으로 0 을 반환합니다. 이 예제에서는 return 0; 을 명시 적으로 작성할 필요가 없습니다 return 0; .

    void 형을 돌려주는 함수를 제외 해, 다른 모든 함수는, 반환 값의 형태에 따라 명시 적으로 값을 돌려 줄 필요가 있습니다.

  • std::cout << "Hello World!" << std::endl; "Hello World!"를 인쇄합니다. 표준 출력 스트림 :

    • std네임 스페이스 이고 :: 는 네임 스페이스 내에서 이름별로 개체를 조회 할 수있는 범위 분석 연산자 입니다.

      많은 네임 스페이스가 있습니다. 여기서는 :: 를 사용하여 std 네임 스페이스에서 cout 을 사용하고자 함을 보여줍니다. 자세한 내용은 Scope Resolution Operator - Microsoft Documentation을 참조하십시오.

    • std::coutiostream 정의 된 표준 출력 스트림 객체이며 표준 출력 ( stdout )으로 인쇄합니다.

    • <<이 컨텍스트 에서 스트림 삽입 연산자입니다.이 연산자 는 객체를 스트림 객체에 삽입 하기 때문에 호출됩니다.

      표준 라이브러리는 특정 데이터 형식에 대한 데이터 삽입을 출력 스트림에 수행하도록 << 연산자를 정의합니다. stream << content content 을 스트림에 삽입하고 동일하지만 업데이트 된 스트림을 반환합니다. 이렇게하면 스트림 삽입이 연결될 수 있습니다 : std::cout << "Foo" << " Bar"; 콘솔에 "FooBar"를 인쇄합니다.

    • "Hello World!"문자열 리터럴 또는 "텍스트 리터럴"입니다. 문자열 리터럴에 대한 스트림 삽입 연산자는 파일 iostream 정의됩니다.

    • std::endliostream 파일에 정의 된 특수한 I / O 스트림 조작기 객체입니다. 조작자를 스트림에 삽입하면 스트림의 상태가 변경됩니다.

      스트림 조작자 std::endl 은 두 가지 작업을 수행합니다. 첫 번째로 end-of-line 문자를 삽입 한 다음 스트림 버퍼를 플러시하여 콘솔에 텍스트를 표시합니다. 이렇게하면 스트림에 삽입 된 데이터가 실제로 콘솔에 표시됩니다. (스트림 데이터는 대개 버퍼에 저장되고 즉시 플러시하지 않는 한 일괄 적으로 "플러시"됩니다.)

      플러시를 피하는 또 다른 방법은 다음과 같습니다.

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

      여기서 \n 은 개행 문자에 대한 문자 이스케이프 시퀀스 입니다.

    • 세미콜론 ( ; )은 컴파일러에게 명령문이 종료되었음을 알립니다. 모든 C ++ 문과 클래스 정의에는 끝 / 끝 세미콜론이 필요합니다.

코멘트

주석은 C ++ 컴파일러가 기능적 의미로 해석하지 않고 임의의 텍스트를 소스 코드 안에 넣는 방법입니다. 주석은 프로그램의 설계 또는 방법에 대한 통찰력을주기 위해 사용됩니다.

C ++에는 두 가지 유형의 주석이 있습니다.

한 줄 주석

이중 슬래시 시퀀스 // 는 줄 바꿈이 주석이 될 때까지 모든 텍스트를 표시합니다.

int main()
{
   // This is a single-line comment.
   int a;  // this also is a single-line comment
   int i;  // this is another single-line comment
}

C 스타일 / 블록 코멘트

시퀀스 /* 는 주석 블록의 시작을 선언하는 데 사용되며 시퀀스 */ 는 주석의 끝을 선언하는 데 사용됩니다. 텍스트가 다른 유효한 C ++ 구문 인 경우에도 시작 시퀀스와 종료 시퀀스 사이의 모든 텍스트는 주석으로 해석됩니다. 이 주석 구문은 C ++의 전신 언어 인 C :에서 상속되므로 "C 스타일"주석이라고도합니다.

int main()
{
   /*
    *  This is a block comment.
    */
   int a;
}

블록 주석에서 원하는 것을 쓸 수 있습니다. 컴파일러가 */ 기호를 만나면 블록 주석을 종료합니다.

int main()
{
   /* A block comment with the symbol /*
      Note that the compiler is not affected by the second /*
      however, once the end-block-comment symbol is reached,
      the comment ends.
   */
   int a;
}

위의 예는 유효한 C ++ (및 C) 코드입니다. 그러나 블록 주석 안에 /* 를 추가하면 일부 컴파일러에서 경고가 발생할 수 있습니다.

블록 주석은 또한 시작하고 한 줄 내에서 종료 할 수 있습니다. 예 :

void SomeFunction(/* argument 1 */ int a, /* argument 2 */ int b);

댓글의 중요성

모든 프로그래밍 언어와 마찬가지로 주석은 다음과 같은 여러 가지 이점을 제공합니다.

  • 읽고 / 유지하기 쉬운 코드의 명시 적 문서화
  • 코드의 목적과 기능에 대한 설명
  • 코드의 역사 또는 추론에 대한 세부 정보
  • 저작권 / 라이센스, 프로젝트 노트, 특별 감사, 기여자 크레딧 등을 소스 코드에 직접 배치합니다.

그러나 의견에는 또한 단점이 있습니다.

  • 코드의 변경 사항을 반영하기 위해 유지 관리해야합니다.
  • 과도한 의견은 코드가 읽을 수 있도록하는 경향이

명확한 자체 문서화 코드를 작성하여 주석의 필요성을 줄일 수 있습니다. 간단한 예제는 변수, 함수 및 유형에 대해 설명적인 이름을 사용하는 것입니다. 논리적으로 관련된 작업을 이산 함수로 분해하면이 작업이 진행됩니다.

코드를 사용하지 않도록 설정하는 주석 표시 자

개발하는 동안 주석을 사용하여 코드의 일부를 삭제하지 않고 신속하게 비활성화 할 수 있습니다. 이것은 종종 테스팅이나 디버깅 목적에 유용하지만 임시 편집 이외의 다른 스타일에는 적합하지 않습니다. 이것을 종종 "주석 처리"라고합니다.

유사하게, 버전 관리 시스템을 통해 코드의 이력을 탐색하는 것과 비교할 때 거의 가치가없는 반면 파일을 혼란스럽게하므로 참조 목적으로 주석에 구버전의 코드를 유지하는 것은 싫은 일입니다.

기능

함수 는 일련의 명령문을 나타내는 코드 단위입니다.

함수는 인수 나 값을 받아들이고 단일 값을 리턴 할 수도 있고 그렇지 않을 수도 있습니다. 함수를 사용하려면 인수 값에 함수 호출 이 사용되며 함수 호출 자체의 사용은 반환 값으로 대체됩니다.

모든 함수에는 형식 시그니처 ( 인수의 유형 및 반환 유형의 유형)가 있습니다.

함수는 프로 시저 및 수학 함수의 개념에서 영감을 얻습니다.

  • 참고 : C ++ 함수는 본질적으로 프로 시저이므로 수학 함수의 정확한 정의 나 규칙을 따르지 않습니다.

기능은 종종 특정 작업을 수행하기위한 것입니다. 프로그램의 다른 부분에서 호출 할 수 있습니다. 함수는 프로그램의 다른 곳에서 호출되기 전에 선언되고 정의되어야합니다.

  • 참고 : 자주 사용되는 함수 정의는 포함 된 다른 파일에 숨겨져있을 수 있습니다 (편의상 많은 파일에서 재사용 할 수 있음). 이것은 헤더 파일의 일반적인 용도입니다.

함수 선언

함수 선언 은 컴파일러에 이름과 유형 서명이있는 함수의 존재를 선언합니다. 구문은 다음과 같습니다.

int add2(int i); // The function is of the type (int) -> (int)

위의 예에서 int add2(int i) 함수는 컴파일러에 다음을 선언합니다.

  • 반환 유형int 입니다.
  • 함수의 이름add2 입니다.
  • 함수에 대한 인수 는 1입니다.
    • 첫 번째 인수는 int 유형입니다.
    • 첫 번째 인수는 함수의 내용에서 이름 i 됩니다.

인수 이름은 선택 사항입니다. 함수에 대한 선언은 다음과 같을 수도 있습니다.

int add2(int); // Omitting the function arguments' name is also permitted.

one-definition 규칙 에 따라 특정 형식 시그니처가있는 함수는 C ++ 컴파일러에서 볼 수있는 전체 C ++ 코드 기반에서 한 번만 선언되거나 정의 될 수 있습니다. 즉, 특정 유형의 시그니처가있는 함수는 다시 정의 할 수 없으며 한 번 정의해야합니다. 따라서 다음은 C ++이 유효하지 않습니다.

int add2(int i);  // The compiler will note that add2 is a function (int) -> int
int add2(int j);  // As add2 already has a definition of (int) -> int, the compiler
                  // will regard this as an error.

함수가 아무 것도 반환하지 않으면 반환 형식이 void 로 기록됩니다. 매개 변수를 사용하지 않으면 매개 변수 목록이 비어 있어야합니다.

void do_something(); // The function takes no parameters, and does not return anything.
                     // Note that it can still affect variables it has access to.

함수 호출

함수가 선언 된 후에 함수를 호출 할 수 있습니다. 예를 들어, 다음 프로그램은 main 함수 내에서 2 의 값을 가진 add2 를 호출합니다.

#include <iostream>

int add2(int i);    // Declaration of add2

// Note: add2 is still missing a DEFINITION.
// Even though it doesn't appear directly in code,
// add2's definition may be LINKED in from another object file.

int main()
{
    std::cout << add2(2) << "\n";  // add2(2) will be evaluated at this point,
                                   // and the result is printed.
    return 0;  
}

여기서 add2(2) 는 함수 호출을위한 구문입니다.

함수 정의

함수 정의 *는 본문 내에서 함수가 호출 될 때 실행되는 코드를 포함한다는 점을 제외하고는 선언과 유사합니다.

add2 에 대한 함수 정의의 예는 다음과 같습니다.

int add2(int i)       // Data that is passed into (int i) will be referred to by the name i
{                     // while in the function's curly brackets or "scope."
                    
    int j = i + 2;    // Definition of a variable j as the value of i+2.
    return j;         // Returning or, in essence, substitution of j for a function call to
                      // add2.
}

함수 오버로딩

같은 이름이지만 매개 변수가 다른 여러 함수를 작성할 수 있습니다.

int add2(int i)           // Code contained in this definition will be evaluated
{                         // when add2() is called with one parameter.
    int j = i + 2;
    return j;
}

int add2(int i, int j)    // However, when add2() is called with two parameters, the
{                         // code from the initial declaration will be overloaded,
    int k = i + j + 2 ;   // and the code in this declaration will be evaluated
    return k;             // instead.
}

두 함수 모두 add2 라는 동일한 이름으로 호출되지만 실제로 호출되는 실제 함수는 호출하는 매개 변수의 양과 유형에 직접 의존합니다. 대부분의 경우 C ++ 컴파일러는 호출 할 함수를 계산할 수 있습니다. 경우에 따라 유형을 명시해야합니다.

기본 매개 변수

함수 매개 변수의 기본값은 함수 선언에서만 지정할 수 있습니다.

int multiply(int a, int b = 7); // b has default value of 7.
int multiply(int a, int b)
{
    return a * b;               // If multiply() is called with one parameter, the
}                               // value will be multiplied by the default, 7.

이 예제에서 multiply() 는 하나 또는 두 개의 매개 변수를 사용하여 호출 할 수 있습니다. 하나의 매개 변수 만 주어진 경우 b 는 기본값 7을 갖습니다. 기본 인수는 함수의 후자 인수에 있어야합니다. 예 :

int multiply(int a = 10, int b = 20); // This is legal 
int multiply(int a = 10, int b);      // This is illegal since int a is in the former

특수 함수 호출 - 연산자

C ++에는 name_of_function(value1, value2, value3) 과 다른 구문을 갖는 특수 함수 호출이 있습니다. 가장 일반적인 예는 운영자의 예입니다.

컴파일러에 의해 함수 호출로 축소 될 특정 특수 문자 시퀀스 (예 : ! , + , - , * , % , << 등등. 이러한 특수 문자는 일반적으로 비 프로그래밍 용도와 연관되거나 미학을 위해 사용됩니다 (예 : + 문자는 일반적으로 C ++ 프로그래밍 및 초등 수학 모두에서 추가 기호로 인식됩니다).

C ++은 특수 문자로 이러한 문자 시퀀스를 처리합니다. 본질적으로 연산자의 각 발생은 함수 호출로 축소됩니다. 예를 들어 다음 C ++ 표현식은 다음과 같습니다.

3+3

다음 함수 호출과 동일합니다.

operator+(3, 3)

모든 연산자 함수 이름은 operator 시작합니다.

C ++의 직계 전임 (C)에서는 C ++에서 다른 유형의 시그니처가있는 추가 정의를 제공하여 연산자 함수 이름을 다른 의미로 지정할 수 없지만 이것이 유효합니다. 하나의 고유 한 함수 이름 아래에 추가 함수 정의를 숨기는 것은 C ++에서 연산자 오버로드 라고하며 C ++에서는 상대적으로 보편적이지만 범용이 아닙니다.

함수 프로토 타입 및 선언의 가시성

C ++에서는 코드를 사용하기 전에 선언하거나 정의해야합니다. 예를 들어, 다음은 컴파일 타임 오류를 생성합니다.

int main()
{
  foo(2); // error: foo is called, but has not yet been declared
}

void foo(int x) // this later definition is not known in main
{
}

이를 해결하는 방법은 두 가지가 있습니다. foo() 의 정의 또는 선언을 main() 사용하기 전에 두는 것입니다. 한 가지 예가 있습니다.

void foo(int x) {}  //Declare the foo function and body first

int main()
{
  foo(2); // OK: foo is completely defined beforehand, so it can be called here.
}

그러나 사용하기 전에 "프로토 타입"선언 만 넣고 나중에 함수 본문을 정의하여 함수를 "전달 선언"할 수도 있습니다.

void foo(int);  // Prototype declaration of foo, seen by main
                // Must specify return type, name, and argument list types
int main()
{
  foo(2); // OK: foo is known, called even though its body is not yet defined
}

void foo(int x) //Must match the prototype
{
    // Define body of foo here
}

프로토 타입은 반환 형식 ( void ), 함수 이름 ( foo ) 및 인수 목록 변수 유형 ( int )을 지정해야하지만 인수 이름은 필요하지 않습니다 .

이것을 소스 파일의 구성에 통합하는 일반적인 방법은 모든 프로토 타입 선언을 포함하는 헤더 파일을 만드는 것입니다.

// foo.h
void foo(int); // prototype declaration

다른 곳에서 전체 정의를 제공하십시오.

// foo.cpp --> foo.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
void foo(int x) { } // foo's body definition

그런 다음, 일단 컴파일되면 해당 오브젝트 파일 foo.o 가 링크 된 단계 인 main.o 에서 사용되는 컴파일 된 오브젝트 파일에 링크됩니다.

// main.cpp --> main.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
int main() { foo(2); } // foo is valid to call because its prototype declaration was beforehand.
// the prototype and body definitions of foo are linked through the object files

함수 프로토 타입호출 이 있지만 함수 본문 이 정의되지 않은 경우 "확인되지 않은 외부 기호"오류가 발생합니다. 컴파일러는 최종 연결 단계까지 오류를보고하지 않으며 오류를 표시하기 위해 코드에서 어떤 행으로 이동할지 모르기 때문에 문제를 해결하기가 어려울 수 있습니다.

표준 C ++ 컴파일 프로세스

실행 가능한 C ++ 프로그램 코드는 대개 컴파일러에 의해 생성됩니다.

컴파일러 는 프로그래밍 언어의 코드를 컴퓨터에서 직접 실행 가능한 (더) 다른 형식으로 변환하는 프로그램입니다. 컴파일러를 사용하여 코드를 번역하는 것을 컴파일 이라고 합니다.

C ++은 컴파일 프로세스의 형태를 "상위"언어 인 C에서 상속받습니다. 아래는 C ++에서 네 가지 주요 컴파일 단계를 보여주는 목록입니다.

  1. C ++ 전처리 기는 포함 된 헤더 파일의 내용을 소스 코드 파일에 복사하고 매크로 코드를 생성하며 #define을 사용하여 정의 된 기호 상수를 해당 값으로 바꿉니다.
  2. C ++ 전 처리기에서 생성 된 확장 소스 코드 파일은 플랫폼에 적합한 어셈블리 언어로 컴파일됩니다.
  3. 컴파일러에 의해 생성 된 어셈블러 코드는 플랫폼에 적합한 객체 코드로 어셈블됩니다.
  4. 어셈블러에서 생성 된 오브젝트 코드 파일은 실행 파일을 생성하는 데 사용되는 라이브러리 함수의 오브젝트 코드 파일과 함께 링크됩니다.
  • 참고 : 일부 컴파일 된 코드는 함께 링크되지만 최종 프로그램을 만들지는 않습니다. 일반적으로이 "링크 된"코드는 다른 프로그램에서 사용할 수있는 형식으로 패키지화 할 수도 있습니다. 이 "패키지 된 사용 가능한 코드의 묶음"은 C ++ 프로그래머가 라이브러리 로 참조하는 것 입니다.

많은 C ++ 컴파일러가 컴파일 프로세스의 특정 부분을 병합하거나 병합 해제하여 쉽게 또는 추가 분석을 할 수 있습니다. 많은 C ++ 프로그래머는 서로 다른 도구를 사용할 것입니다. 그러나 모든 도구는 일반적으로 프로그램 제작에 참여할 때이 일반화 된 프로세스를 따릅니다.

아래 링크는이 토론을 확장하고 도움이되는 멋진 그래픽을 제공합니다. [1] : http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html

전처리 기

전처리 기는 컴파일러 의 중요한 부분입니다 .

그것은 소스 코드를 편집하고, 비트를 잘라내고, 다른 것들을 바꾸고, 다른 것들을 추가합니다.

소스 파일에는 사전 처리기 지시문을 포함 할 수 있습니다. 이 지시문은 전처리 기가 특정 작업을 수행하도록 지시합니다. 지시문은 새 행의 #으로 시작합니다. 예:

#define ZERO 0

만날 첫 번째 전 처리기 지시문은 아마도

#include <something>

지령. 그것이하는 일은 모든 something 취하고 그 지시어가있는 곳의 파일에 삽입하는 것입니다. 안녕하세요 세계 프로그램은 라인으로 시작합니다.

#include <iostream>

이 행은 표준 입력 및 출력을 사용할 수 있도록하는 함수 와 객체를 추가합니다.

전 처리기를 사용하는 C 언어는 C ++ 언어만큼 많은 헤더 파일 을 가지고 있지 않지만 C ++에서는 모든 C 헤더 파일을 사용할 수 있습니다.


다음 중요한 지시어는 아마도

#define something something_else

지령. 이것은 파일을 따라 간다,가 발생할 때마다 교체해야합니다 전처리 말해 somethingsomething_else . 또한 함수와 비슷한 것을 만들 수도 있지만, 아마도 고급 C ++로 간주됩니다.

something_else 필요하지 않습니다,하지만 당신은 정의하면 something 처리기 지시문의 바깥에 아무것도 등을, 모든 항목 something 사라질 것입니다.

이것은 #if , #else#ifdef 지시어 때문에 실제로 유용합니다. 이들의 형식은 다음과 같습니다.

#if something==true
//code
#else
//more code
#endif

#ifdef thing_that_you_want_to_know_if_is_defined
//code
#endif

이 지시문은 true 비트에있는 코드를 삽입하고 false 비트를 삭제합니다. 이것은 전체 코드를 다시 작성할 필요없이 특정 운영 체제에만 포함되는 비트의 코드를 사용하는 데 사용될 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow