전체 페이지뷰

2014년 10월 7일 화요일

3. C에서 C++로.....(2)

<C에서 C++로>

  • Namespace(이름공간)과 사용법
  • std와 cout,endl,cin
  • using

강의 세번째시간입니다. 내용중에 잘못되거나 부족한 부분이 있으면 지적 부탁드리겠습니다. 그럼 오늘도 즐겁게 공부해 보도록합시다.

Namespace(이름공간)이란 무엇일까요. 전혀 감이 잡히지 않는것이 당연합니다.
간단한 예를 들어 설명하도록 할게요.

철수는 덕구라는 강아지를 키우고있습니다. 덕구를 데리고 공원을 산책하는 도중에 영희와 희동이를 만나게되었습니다. 영희와 희동이도 강아지를 데리고 공원에 산책을 나왔던것이었네요. 철수가 영희와 희동이에게 너네 강아지 이름이 뭐냐고 물었습니다. 영희, 희동이 둘다 '덕구' 라고 대답했습니다. '덕구'라는 같은 이름을 가진 강아지가 셋이되어버렸군요.

위와같은 상황에서 우리는 세마리의 덕구를 어떻게 구분할까요? 대부분 이렇게 구분을할겁니다.
    *철수네 덕구
    *영희네 덕구
    *희동이네 덕구
다들 공감하시나요? 철수네~, 영희네~, 희동이네~ 이게 namespace입니다. 이미 여러분들은 namespace를 현실에서 사용하고 계셨던겁니다.

실제로 프로그램도 대형화가 되면서 함수, 변수등의 이름들이 충돌되는 경우가 많아지게 되었습니다. 위에 예처럼말이죠. 만약 충돌되는 함수와 변수들의 이름을 모두 바꾸어야한다면 여간 성가시고 정신없는 문제가 아닐수 없습니다. Namespace는 이런 문제에 대해 탁월한 해결책을 제시해주고 있습니다.

Namespace 사용법을 알아보도록 하겠습니다.




보이는 예제와 같이 Duckoo()이라는 동일한 이름과 매개변수를 가진 함수를 선언하게 되면 어떻게 될까요?

이렇게 멋진 에러가 하나 등장하게 될겁니다. 당연히 컴퓨터 입장에서는 어떤 함수를 사용해야될지 어리둥절 하겠지요.
그럼 저기~ 위에서 배운대로 철수네, 영희네, 희동이네 처럼 Namespace를 만들어주어서 구분을 하게 해주면 되겠지요?

위에 예제에 다음과같이 코드를 추가하여 보도록 하겠습니다.



Duckoo()라는 함수 두개에 namespace {  } 를 씌워주었습니다.  정말 간단한 사용방법이지요? 저렇게 cheolsoo, younghee namespace를 선언해주면, 앞으로 Duckoo()는 철수네 Duckoo(), 영희네 Duckoo()로 구분이 가능해 지는것입니다. 구분이된 함수는 가져다 사용할때 "누구의" Duckoo()인지 반드시 명시를 해줘야합니다. 
main() 함수를 보면 다음과 같이 사용을 하고있습니다.

cheolsoo::Duckoo(10,5);
( 철수라는 네임스페이스에 정의된 Duckoo()라는 함수를 사용할 것이다!)

younghee::Duckoo(10,10);
( 영희라는 네임스페이스에 정의된 Duckoo()라는 함수를 사용할 것이다!)
앞부분에는 namespace를 뒤에는 함수또는 변수이름을 마지막으로 사이에 구분자 :: 를 넣어 사용해줍니다. 
namespace :: 함수, 변수등의 이름;
어때요 사용방법은 상당히쉽죠?
이제 네임스페이스가 무엇인지 확실히 개념이 잡혀가고 있습니다.

다음 예제처럼 함수의 선언과 정의를 따로따로 나누어해도 됩니다.


namespace :: 함수, 변수등의 이름; 선언방법이 함수를 호출하는데만 사용하는것이 아니라 함수를 정의할때도 위의 예제처럼 활용할 수 있습니다. 이런 방법도 있구나 하고 잘 익혀두시길 바랍니다. 컴파일 결과는 이전 과 동일합니다.

다음예제를 통해 namespace가 가지는 특성을 알아보겠습니다.




위 소스코드를 보시면 cheolsoo라는 이름의 namespace가 중복되게 사용되고 있음을 확인 하실 수 있을겁니다. 하지만 컴파일은 아주 잘되는군요.
namespace는 함수와는 다르게 이름의 중복을 허락합니다. 다시말해 위의 예제처럼 namespace를 둘 이상으로 나누어서 선언을 해도 이 둘은 동일공간이된다는 말이죠.
따라서,

namespace cheolsoo
{
   int Duckoo();
   void marry();
}                     //이렇게 코드를 쓰나

namespace cheolsoo
{
  int Duckoo();
}

namespace cheolsoo
{
  void marry();
}                      // 이렇게 코드를 쓰나
모두 똑같다는 말이됩니다. 이점 염두해두세요~

namespace younghee{} 를 보시면 그안에 namespace second, third가 정의되어있는 것을 볼수있습니다. namespace안에 이름이 다른 네임스페이스를 선언을해도 된다는걸 알 수있습니다.
이렇게 정의된 namespace안에 함수나 변수를 호출할때는 namespace의 포함관계에 순서에따라 이전에 호출하던 문장을 사용해주면됩니다. 이렇게말이죠.

younghee::third::marry();
younghee::secon::Duckoo();

네임스페이스::네임스페이스::함수또는변수이름;
어때요 참 쉽죠?
이렇게 알아두셨으면 위 예제는 이해하는데 문제가 없을거라 생각합니다.

예제를 쭉~ 풀어오면서 이상한 부분을 발견하지 않으셨나요??
아마 다들 궁금해하셨던 부분이있을거에요 . 우리가 지금까지 계속 사용해왔던 입출력에 관한 함수! 바로 std::cout, std::endl, std::cin 이 녀석들도 뭔가 수상하다!
네임스페이스를 알게되므로서 우리는 이 녀석들의 정체를 조금 알 수 있습니다.

namespace std라는 곳에 정의된 cout
namespace std라는 곳에 정의된 endl
namespace std라는 곳에 정의된 cin 
그렇다면 std라는 namespace는 어디에 있을까?
바로 <iostream>이라고 맨첫줄에 선언한 헤더파일에 정의되어 있답니다.

어떻게 구현된 함수인지 내용은 정확히 모르지만 이제는 조금 알게되었습니다. 기쁘지않습니까?
조금만 더 배우면 이 녀석들을 완전히 파헤칠수 있는 날이 머지않았습니다. 조금만더 힘내요~

사람은 항상 귀찮은걸 싫어합니다. 저도 역시 귀찮은게 너무싫어요. 매번 namespace를 이용하여 함수와 변수를 정의하면 항상 (예를들어) std::, cheolsoo::, younghee::second.. 이렇게 사용해야 되는걸까요? 답은 No 입니다.
다음예제를 보면 앞으로 손가락이 좀더 편하실겁니다.



맨 첫줄 using namespace std; 보이시나요?
무슨 의미인가 하면 'namespace std안에 정의된 모든 것을 사용할때 namespace 명시를 안해도됩니다' 이런뜻입니다. 그럼 이말이 사실인지 알아보도록하죠.

main() 함수를 보니 std::cin, std::cout, std::endl 로 사용했던것이 cin, cout, endl로 간소화가 되었습니다. using 키워드 너무너무 고맙네요.

이렇게 길고긴 namespace의 단원이 끝났네요. 다들 이해가 잘되셨으면 좋겠습니다.
오늘강의도 고생많으셨고, 다음가의때 뵙도록 하겠습니다. 화이팅!





















댓글 없음:

댓글 쓰기