강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

kairos님의 프로필 이미지
kairos

작성한 질문수

홍정모의 따라하며 배우는 C++

1.1 프로그램의 구조

namespace 와 iostream 순서

작성

·

1K

0

답변 감사합니다 조이님!

조금 너무 지엽적인 질문일 수 있어 조심스러운데

답변 중

"iostream이라는 library 속의 std라는 namespace인 부분집합 관계로 봐야할까요?" 라고 말씀하셨는데 그 반대로 보면 될 것 같아요. library 내용은 std 안에 속해 있습니다. 

여담으로 iostream 는 수 많은 c++ standard 라이브러리 중 하나일 뿐입니다. "

1) using namespace std; 가 iostream보다 큰 범위인데

#include <iostream>보다 먼저 써주는 이유가 뭔가요? 

수학적으로는 큰 범위를 먼저 써주고 작은 범위인 iostream을 쓰는 게 맞지 않나요?

2) using namespace std; 가 큰 범위라면 

#include <iostream>을 다시 한 번 명시하는 이유가 있나요?

using namespace std; 만 쓰는 게 효율적이지 않나요?

이 부분이 어색하게 느껴지는게 

  1. namespace std 가 더 큰 범위인데 2번째에 써줌.
  2. using namespace 안에 cin과 cout이 있는데 
    #include <iostream> 을 선언한 후에 using namespace를 씀.

두 가지 이유때문에 조금 부자연스러운 것 같습니다. 

단순히 포함관계가 아니여서 그런건가요?

 

답변 1

4

안녕하세요 :)

음.. 이건 헤더파일과 네임스페이스에 대한 이해가 있으셔야할 것 같아요.

챕터 1 후반 부에서 헤더 파일과 전처리 과정에 대해서 배우기 때문에 챕터 1 강의를 전체적으로 들으신 후에 다시 한번 더 생각해보시길 권합니다.

그래도 간단하게 설명드려 보자면..

우선 아셔야할 부분은 namespace 는 파일과는 전혀 상관 없이, "같은 이름"이라면 같은 공간이라는 것입니다. 

a.cpp 라는 파일에서 namespace aaa 를 정의하고 이 aaa 안에 코드를 작성하고

전혀 다른 b.cpp 라는 파일에서도 namespace aaa 를 정의하고 이 aaa 안에 코드를 작성했다고 가정해볼게요.

그럼 속해있는 파일은 전혀 다르지만 aaa 라는 같은 이름을 가진 공간 내에 정의된 코드들이기 때문에 a.cpp 파일의 aaa 내에서 정의된 여러 변수 함수들은 b.cpp 파일의 aaa 내에서 정의된 여러 변수 함수들과 aaa 라는 이름의 같은 그룹에 속해있다고 보시면 됩니다.

iostream, algorithm, vector 등등.. 이 모든 라이브러리들은 c++ 에서 기본적으로 제공하는 헤더 "파일"이나 마찬가지인데요,

이 파일들 안에 namespace std {   .....  } 가 정의되어 있고 이 std 네임스페이스 안에 cin, cout 등등 이런게 정의되어 있는 형태입니다. 

즉, 우리가 iostream 라이브러리를 통해서 사용하는 cin, cout 이런 코드 내용들은 std 네임스페이스 안에 정의되어 있다고 봐도 무방한거에요. 

그리고 헤더 파일과 네임스페이스는 서로 완전히 다른거에요!!! 서로 역할이 다릅니다. (그래서 사실 포함 관계를 따지기도 좀 이상하게 느껴집니다.) 헤더 파일은 말 그대로 파일이구요 (코드가 작성된 파일) 네임 스페이스는 이름을 구분해주는 문법 정도로 생각해주시면 되요. 그냥 "이름표" 정도라고 생각해주시면 되요! 

using namespace std; 는 이 파일 내에서 std 라는 네임 스페이스를 사용하겠다고 하는 선언문이며 std:: 를 생략하는 효과 정도 밖에는 없습니다. 그리고 네임스페이스의 역할은 말 그대로 "이름 공간"인데요, 같은 이름 충돌을 방지하기 위해서, 이름을 구분해주기 위해 등장한 문법 정도로 생각해주시면 됩니다. 같은 범위 내에 이름이 같은 변수나 함수는 또 다시 정의할 수가 없는데요, 같은 이름을 가진 변수라도 속한 네임스페이스가 다르면 다른 변수로 정의되기에 편한 점이 많습니다. 같은 이름의 '철수' 라도 201 호에 사는 철수와 202 호에 사는 철수는 다르듯이 그렇게 속해있는 namespace 로 같은 이름도 구분지을 수 있도록 한번 더 그룹화 하기 위해 등장한 문법일 뿐이에요. C++ 표준은 std 네임스페이스로 그룹화 한 번 해준 것 뿐이구요. C++ 에서 standard 의미를 알리기위해 std 라는 "이름표"를 붙여준거에요. 다시 말씀 드리지만 using namespace std; 는 모든 C++ 표준을 불러오겠다 이런 의미가 절대 아닙니다. std 네임스페이스로 "이름이 구분지어진" C++ 표준 변수 함수 등등을 여기서 자주 사용할 것이니 std:: 를 생략하겠다 이 정도의 의미에요. 

반면 #include <iostream> 은 iostream 이라는 "헤더 파일" 을 불러오겠다는 의미입니다. 이 헤더 파일 안에 작성되어 있는 cin, cou 들은 그냥 "이름 공간"인 std 에 속해있는 것 뿐이구요(속했다 보단 그냥 std 라는 "이름표"가 붙어있다고 생각해주세요), 이 cin, cout 들을 사용하기 위해선 이 헤더파일 전체 코드를 내가 지금 작성하고 있는 cpp 파일에 전부 복사해와야겠죠? 이렇게 헤더파일 전체 코드를 복사해주는 과정을 해주는게 #include <iostream> 전처리문인 것입니다. 이걸 해주지 않으면 cin, cout 같이 iostream 에 정의되어있는 모든 객체, 함수들을 사용하실 수가 없어요. 

cin, cout 은 iostream 파일 안에 작성이 되어 있으며 std 라는 이름 공간에 포함되어 있긴 하지만 이 std 는 그냥 이름을 구분해주는 역할 정도인 것 뿐이에요. 네임스페이스와 헤더파일은 역할이 전혀 다른 것이니 따로 구분해서 생각하셔야 합니다. 그리고 #include <iostream> 을 먼저 쓰든, using namespace std 를 먼저 쓰든 아무 상관이 없습니다.

#include <iostream> 👉 cin, cout 등등 여러 입출력 함수를 사용할 수 있게 됨. iostream 헤더 파일에 이 함수, 변수 코드들이 작성되어 있는데 이 헤더 파일의 모든 코드 내용을 복사해오겠다는 문장이기 때문. 이게 없으면 cin, cout 등등 사용할 수 없음. 

using namespace std 👉 std::cin, std::cout 이라고 안써도 되고 cin, cout 으로만 쓸 수 있게 std:: 생략 가능해짐. 끝. (cin, cout 사용가능 여부와는 전혀 상관이 없습니다. 귀찮음을 덜어주는 선언문일 뿐이에요.)

제가 말씀드리는게 이해가 안되셔도 괜찮은게.. 어차피 챕터 1 후반부에서 다 배웁니다. extern 배우실 때도 헤더파일 처리 과정에 대해 한번 더 생각해보실 기회가 생기구요. 질문자님께서 질문 주신 내용을 보니 네임스페이스와 헤더 파일을 구분하는 것과 헤더파일의 역할과 전처리 과정에 대해 아직 안 배우셔서 질문 주신 것 같다는 생각이 들어서 말씀 드립니다. :)

kairos님의 프로필 이미지
kairos

작성한 질문수

질문하기