C++ 튜토리얼
C ++ 시작하기
수색…
비고
'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::cout
은iostream
정의 된 표준 출력 스트림 객체이며 표준 출력 (stdout
)으로 인쇄합니다.<<
는 이 컨텍스트 에서 스트림 삽입 연산자입니다.이 연산자 는 객체를 스트림 객체에 삽입 하기 때문에 호출됩니다.표준 라이브러리는 특정 데이터 형식에 대한 데이터 삽입을 출력 스트림에 수행하도록
<<
연산자를 정의합니다.stream << content
content
을 스트림에 삽입하고 동일하지만 업데이트 된 스트림을 반환합니다. 이렇게하면 스트림 삽입이 연결될 수 있습니다 :std::cout << "Foo" << " Bar";
콘솔에 "FooBar"를 인쇄합니다."Hello World!"
는 문자열 리터럴 또는 "텍스트 리터럴"입니다. 문자열 리터럴에 대한 스트림 삽입 연산자는 파일iostream
정의됩니다.std::endl
은iostream
파일에 정의 된 특수한 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 ++에서 네 가지 주요 컴파일 단계를 보여주는 목록입니다.
- C ++ 전처리 기는 포함 된 헤더 파일의 내용을 소스 코드 파일에 복사하고 매크로 코드를 생성하며 #define을 사용하여 정의 된 기호 상수를 해당 값으로 바꿉니다.
- C ++ 전 처리기에서 생성 된 확장 소스 코드 파일은 플랫폼에 적합한 어셈블리 언어로 컴파일됩니다.
- 컴파일러에 의해 생성 된 어셈블러 코드는 플랫폼에 적합한 객체 코드로 어셈블됩니다.
- 어셈블러에서 생성 된 오브젝트 코드 파일은 실행 파일을 생성하는 데 사용되는 라이브러리 함수의 오브젝트 코드 파일과 함께 링크됩니다.
- 참고 : 일부 컴파일 된 코드는 함께 링크되지만 최종 프로그램을 만들지는 않습니다. 일반적으로이 "링크 된"코드는 다른 프로그램에서 사용할 수있는 형식으로 패키지화 할 수도 있습니다. 이 "패키지 된 사용 가능한 코드의 묶음"은 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
지령. 이것은 파일을 따라 간다,가 발생할 때마다 교체해야합니다 전처리 말해 something
에 something_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 비트를 삭제합니다. 이것은 전체 코드를 다시 작성할 필요없이 특정 운영 체제에만 포함되는 비트의 코드를 사용하는 데 사용될 수 있습니다.