C++

std, ::, <<

sgwon 2021. 9. 18. 23:59

뇌가 조금이라도 싱싱할때 공부할 걸. 괜찮아 지금도 나름 싱싱해.

참고도서 : 윤성우 저 열혈강의 C++ 프로그래밍 개정판

#include <iostream>

int main(void){
    std::cout<<"hello world!"<<std::endl;
    return 0;
}

컴퓨터전공을 하며 C++을 이리 본격적으로 공부하는 것은 처음이다. 다른 언어들은 수강을 들으며 자연스럽게 배웠지만 신기하게도 C++은 순수독학으로 공부를 하던 분위기였다. 외계어 같던 코드들이 익숙해지고 파이썬을 시작으로 다른 언어를 공부하고 있던 나에게

 

std, ::, <<, endl

가 코드속에 박혀있는 C++은 다시 외계어처럼 느껴졌다. 보통 대부분의 언어들은 비슷한 신택스를 가지고 그로인해 하나의 언어를 배우게 되면 다른 언어학습에 대한 진입장벽이 낮아진다. 그렇게 느끼던 나에게 C++은 다른 언어보다 벽이 높아보였고 미루다 보니 이제서야 공부를 시작하게 된거 아닌가 싶다.

기왕 이렇게 시작하게 된거, 내게 벽을 느끼게 해준 저 친구들을 좀 깊게 알아보자.


저게 print라고?

std::cout<<name<<' :'<<num<<std::endl;
//ㅋ에이저게무슨프린트야

출력 하나를 하기엔 너무나도 번거롭다.

'std'는 뭐고 '::'는 뭐고 '<<'는 크기비교하는 연산자 아닌가? 끝에 'endl'는 end인거는 알겠는데 l은 왜 붙은거지?

 

다시보니 별거아니네?

<<의 역할은 생긴거 그대로 '연이어서'와 비슷하다. 위 코드로 예를 들면 name 변수와 '  : ', num변수를 모두 이어서 하나의 string으로 출력하는 것이다. 다른 프로그램 언어에서는 단순히 컴마(,)를 사용하거나 +연산자로 묶어서 쓸 수도 있었던 거 같다. 별거 아니네.

 

마지막에 endl

endl이거는 뭐 그냥 출력마치면 '<<std::endl;'붙이면 된다고 생각하면 편하게 넘어가겠지만 뭔가 저걸 제대로 알면 앞으로 C++공부에 좋은 도움이 될 거라 생각했다.

int num=4;
std::cout<<"Hello "<<"World!"<<std::endl;
std::cout<<num<<' '<<'A'<<std::endl;
std::cout<<' '<<3.14<<std::endl;

저 코드들을 실행하면 뭐가 나올까?

Hello World!
4 A
 3.14

그러면 만약에 std::endl를 제거한다면? 옆의 <<도 제거하도록 하자. <<를 써놓고 뒤에 이을 것이 없으면 오류가 날 것이 뻔할 거다.

int num=4;
std::cout<<"Hello "<<"World!";
std::cout<<num<<' '<<'A';
std::cout<<' '<<3.14;
Hello World!4 A 3.14

다시 말해서 std::endlendline인 것이다! "\n"이라고 생각하면 될 거 같다. 근데 endl가 "\n"라면 std는 뭐고 둘 사이의 ::는 뭐지?

'우리는 아직 std::cout와 <<연산자, 그리고 std::endl의 정체를 모른다. 다만 사용할 줄만 알뿐이다. 하지만 진도를 나가면서 이들의 정체도 서서히 밝혀지게 될 것이다.' - 책에서

하지만 나는 지금 궁금하기 때문에 검색해서 알아봤다.

std(namespace,이름공간),  ::(scope resolution operator,스코프분석연산자)

구글링을 통해 찾아보니

std는 곧 standard이며 말그대로 C++에서 사용하는 대부분의 기능이 들어가 있는 헤더파일이다. 

헤더파일? '.h'이거? 난이거 선언한 적이 없는데

나는 여기서 C++의 새로운 특징을 알게 되었다. 바로 namespace이다. 말그대로 이름을 정해주는 건데 목적은 명확한 함수의 사용을 위함이다. 예를 들어 해적선의 선장이 선원에게 저 앞에서 앨리스를 찾으라는 명령을 받았다고 하자. 그러면 선원은 스코프(scope)로 앞에 있는 앨리스를 찾을 것이다. 그런데 앞에 섬이 두개가 있는데 두 섬에 동명이인인 앨리스가 한명씩 살고 있는 것이다. 물론 이상황에서는 찍거나 선장에게 다시 물어볼 수 있지만 프로그램에서는 이게 불가능하다. 만약 이게 선원이 아니라 코드였다면 에러를 일으켰을 것이다. 그래서 필요한 것이 '세부적인 설명'이다.

"독도에 살고 있는 앨리스를 찾아라."

선장이 이렇게 말했다면 독도에 앨리스가 여러명이 있지 않고서야 쉽게 찾을 수 있을 것이다. 예시는 여기까지만 하고 이를 프로그래밍 언어로 변환해보자.

std::cout ↔ std에 정의 되어있는 cout함수를 사용한다.

여기서 자연스럽게 ::의 용도와 의미를 알게 되는데 이 ::를 스코프분석연산자(scope resolution operator)라고 한다

이러니 이해가 간다. 이렇게 되면 cout의 마지막에 <<std::endl을 붙인 것도 std라는 이름공간(namespace)에 정의된 endl이라는 함수는 "\n"을 출력하는 함수이기 때문에 그와 같은 결과가 나온 것이다.

그러면 여기서 std는 뭐지? 우리가 처음에 include한 iostream.h(Input/Output Stream(입출력 스트림))을 지칭하는 이름이라고 봐도 손색이 없을 것이라 본다. 저 헤더파일에 공간이 std라는 namespace로 되어있어 우리는 이를 사용한 것이다.

그런데 실은 이름공간을 사용하는 다른 방법이 있다.

#include <iostream>
using namespace std;

int main(void){
    cout<<"Hello World!"<<endl;
    return 0;
}//Hello World!

이와 같이 처음에 선언해 주는 것 만으로 우리는 std::를 굳이 앞으로 붙일 필요가 없는 것이다. 스코프분석연산자 안녕!

이러한 이름공간은 우리가 새로운 헤더파일을 만들정도로 엄청 큰 프로그램을 코딩하거나 C++로 프로젝트를 진행할 경우, 어쩔수 없이 함수의 이름이 겹칠때 아주 요긴하게 쓰일 것이다.


단순한 출력에서 들었던 의문을 풀어나가다보니 namespace와 iostream.h까지 들여다 보게 되었다. 하지만 앞으로 배울 것이라며 참는 것은 별로 내 성격에 맞지 않는다. 궁금한게 있으면 왜 이게 이렇게 되는지 알아내고 말아야 마음이 편해진다. 이게 진짜 공부가 아닐까싶다. 근데 뭔가 많이 공부한 거 같지만 실질적으로는 아직 C++로는 출력밖에 못하는 반푼이다.

입력이나 if문, for문, while문을 앞으로 공부하게 될 건데 내 블로그에는 내가 호기심을 느꼈던 것들만 남기고 싶다. 

그말인 즉슨 위에 말한 이 카테고리에는 다른언어에서도 볼법한 흔한 문법이나 함수는 올리지 않고, 내가 C++을 공부하며

'어 이건 C++의 특징이라고 할만한 걸?'라고 느낀 것만 올릴 것이라는 거다. 많이 글을 올릴 수 있게 되면 좋겠다.