안녕하세요? 수구리입니다. (어색;)
오늘부터 본격적으로 책을 펼치게 되었습니다.
우선 어떤 언어를 처음 접하던지 가장 먼저 하는것은 아니, 해야하는 것은바로 Hello World 프로그램을 작성하는 것 같습니다. 그렇다면 이 간단한 프로그램안에는 어떤 것들이 숨어있는지 알아보도록 하겠습니다.
우선 프로그램을 먼저 살펴보도록 하겠습니다!
// helloworld.cpp
#include <iostream>
int main() {
std::cout << "hello world!" << std::endl;
return 0;
}
이렇게 어마 무시하게 짧은 코드이지만 이 안에는 무려 네가지의 내용이 들어가 있습니다. 찬찬히 알아보도록 하죠
1. 주석
가장 첫줄에는 " // " 로 시작하는데요. 이는 프로그래머에게 어떤 정보를 제공하는 메시지로 컴파일러는 이 부분을 무시하고 컴파일을 진행합니다. C++에서는 두 가지 형태로 주석을 표현합니다.
- 위의 예제에서와 같이 " // " 로 단일 줄에 대한 주석을 표현
- " /* ~ */ " 를 사용하여 여러 줄에 대한 주석을 표현
요건 뭐 언어마다 다르니까 참고하시면 될 것 같습니다.
2. 전처리 지시자
C++로 작성된 소스 코드는 빌드(Bulid)라는 작업을 거치게 됩니다. 빌드는 총 3단계로 구성되어 집니다.
1. 전처리(preprocess) : 소스 코드에 담긴 메타 정보를 처리한다.
2. 컴파일(complie) : 소스 코드를 머신이 읽을 수 있도록 목적(Object) 파일로 변경한다.
3. 링크(link) : 앞서 변환한 여러 목적 파일들을 애플리케이션으로 엮는다.
또, 지시자란 전처리기에 전달할 사항을 표현하며 위의 예제에서는 #include <iostream> 처럼 " # " 으로 시작합니다.
즉, 쉽게말해서 #include 지시자는 <iostream>을 포함시켜서 현재의 파일에 사용할 수 있도록 가져오라는 것입니다.
C++ 에서 선언은 확장자가 .h 인 헤더 파일에 작성을 하고, 구현은 확장자가 .cpp 인 소스 파일 에서 작성합니다. 여기서 C#과 Java는 선언과 구현을 따로 분리하지 않고 한 파일에 작성하는 다른점이 있죠.
정리하면, 위의 예제에서 만약 <iostream>을 불러오지 않는다면 (즉, include 하지 않으면) 출력하는 작업을 수행할 수 없다는 것입니다.
자주 사용하는 전처리 지시자에 대하여 알아봅시다!
전처리 지시자 | 기능 | 사용 예 |
#include [파일] | 지정한 파일의 내용을 지시자 위치에 넣는다. | 다른 곳에 정의된 함수를 사용할 목적으로 해당 함수의 선언문이 담긴 헤더 파일을 가져온다. |
#define [키] [값] | 코드에서 '키'에 해당하는 값을 모두 '값'으로 치환한다. | C에서는 주로 상숫값이나 매크로를 정의하는데 사용되어짐. C++에서는 더 나아가서 개선된 메커니즘을 제공함. |
#ifdef [키] #endif #ifndef [키] #endif |
지정한 '키'가 #define 문으로 정의가 되었는지의 여부에 따라서 ifdef나 ifndef로 묶인 코드 블록을 포함시키거나 제외한다. [ifdef => if defined] [ifndef => if not defined] |
주로 include 문장이 중복되어서 추가되는 것을 막기 위해서 사용한다. |
#pragma [xyz] | xyz에 대한 구체적인 동작은 컴파일러마다 다르다. 주로 전처리 과정에서 이 지시자에 도달할 떄 경고 또는 에러 메시지를 화면에 표시하는 용도로 사용한다. | 예제 참고 |
중복 include를 막는 예제
#ifndef MYHEADER #define MYHEADER // 헤더 파일에 담을 내용 #endif
최신 컴파일러를 사용하여 중복 include를 막는법
#pragma once // ... 헤더 파일에 담을 내용
대부분 최신 컴파일러는 지원을 해준다고 하니 아래 예제를 사용하면 좋을 것 같습니다!
3. Main 함수
다음은 프로그램의 중심인 Main 함수에 대하여 알아보도록 하겠습니다.
맨 처음 알아본 예제에서는 main 함수의 파라메터가 비어있는데 비워둔다면 자동으로 0을 리턴해 줍니다.
반면에 아래와 같이 두개의 파라메터를 가질 수 있는데 아래와 같습니다!
int main(int argc, char* argv[])
간단하게 알아보자면 argc는 프로그램에 전달할 인수 개수를 말하고,
argv는 배열의 형태를 띄고 있으며 전달할 인수의 값을 담아 줍니다. argv[0]에는 프로그램 이름이 담기는데
여기서 주의할 점은 실제 매개변수의 index는 1부터 시작합니다.
4. I/O 스트림
다음으로는 Input / Output 스트림에 대하여 알아보겠습니다!
이는 뒤에서 자세하게 다룬다고 하는데 간단하게만 알아보자면 출력 스트림은 데이터를 나르는 컨베이어 벨트에 비유할 수 있다고 합니다.
만약, 스트링을 출력하고 숫자를 출력한 다음 또다시 스트링을 출력하고 싶다면 다음과 같이 std::cout 이라는 컨베이어 벨트에 올려놓기만 한다면 된다고 이해하면 쉬울 것 같습니다!
std::cout << "my age is" << 25 << "and I live in.." << std::endl;
이처럼 " << " 기호로 엮어주기만 하면 됩니다. 그리고 마지막에 " endl " 이 부분에서 한 줄의 끝을 의미하고 이 명령어를 만나게 된다면 다음줄로 넘겨주는 개행 역할을 해줍니다. C언어에서는 "\n" 이죠? 그렇습니다.
이 스트림은 사용자로부터 입력을 받을 때에도 유용합니다! 위의 예제에서 " << " 를 사용했던 거와는 반대로 " >> " 연산자를 사용하면 됩니다. 이 입력 스트림에 대한 내용도 뒤에서 자세하게 다룰 예정입니다.
만약 C에 익숙하다면 printf() 또는 scanf() 함수가 없어서 당황을 할텐데 C++에서도 그대로 사용이 가능하지만, 이 두 함수는 타입 안정성을 보장하지 않기 때문에 C++에서는 권장하지 않는다고 합니다.
오늘 이렇게 간단한 Hello World 를 출력하는 예제를 통해 어떠한 내용이 있는지 알아보았습니다.
다음 포스팅에서는 네임스페이스가 무엇인지 알아보도록 하겠습니다. 감사합니다!
'🌈 프로그래밍 > C++' 카테고리의 다른 글
[C++] 1.1.6 타입 (0) | 2021.08.12 |
---|---|
[C++] 1.1.5 연산자 (0) | 2021.08.12 |
[C++] 1.1.3 ~ 1.1.4 리터럴과 변수 (2) | 2021.08.11 |
[C++] 1.1.2 namespace (0) | 2021.08.10 |
[C++] 전문가를 위한 C++ 책을 펼치며.. (5) | 2021.08.08 |