insert_iterator 반복자 활용

 입력 반복자를 이용하여 노드를 삽입시 많이 사용되는 반복자가 insert_iterator이다. 이 반복자를 이용하면 원하는 위치에 노드를 삽입하려 할 때 편하게 작업을 수행할 수 있다. 반복자의 사용 예를 보면 다음과 같다.

#include <iostream>
#include <list>

using namespace std;

int main()
{
  // 스트링을 저장할 리스트 선언 및 첫 번째 스트링 저장
  list<string> strList;
  strList.push_back(“AAA”);

  // 리스트에 데이터를 입력하기 위한 반복자 선언
  insert_iterator<list<string> > listIter(strList, strList.begin());

  // 반복자를 이용한 노드 삽입
  *listIter++ = “EEE”;
  *listIter++ = “DDD”;
  *listIter++ = “CCC”;
  *listIter++ = “BBB”;

  // 출력 반복자와 출력 스트림을 이용하여 화면 출력
  copy(strList.begin(), strList.end(), ostream_iterator<string>(cout, ” “));
}

 예제를 실행하면 EEE ~ BBB 순으로 노드가 저장된 것을 확인할 수 있다.

리스트

 리스트는 순차형 컨테이너이면서 포인터 연산을 수행하기 때문에 특정 노드를 바로 찾아가는 키의 개념이 없다. 따라서 원하는 노드를 찾고자 할 때는 반복자를 이용하여 처음부터 차례대로 노드들을 체크해보아야 한다. 리스트는 이러한 단점에도 불구하고 인의의 노드의 삽입과 삭제가 무척 빠르고 효율적이기 때문에 활용가치가 무척 높은 자료구조이다.

벡터

 벡터는 원소의 상수 레퍼런스를 반환하는 메소드를 제공한다. 이 메소드를 이용하면 벡터 속에 있는 데이터를 바로 얻을 수 있다. 이러한 메소드에는 front(), back() 등이 있다.

 다음은 front()와 back() 메소드의 간단한 사용 예를 보여주고 있다.

strVec.push_back(“A”);  // 벡터 내부: A
strVec.push_back(“B”);  // 벡터 내부: A B
strVec.push_back(“C”);  // 벡터 내부: A B C

cout << “시작: ” << strVec.front() << “, 끝: ” << strVec.back() << endl;

 이 문장을 실행시키면 A와 C의 데이터가 화면에 출력된다.

헤더파일 속의 #ifndef와 #endif 선언

 헤더파일을 보면 다음과 같이 #ifndef와 #endif가 나온다. 이는 3-1.h 헤더파일을 다른 소스파일이 여러 번 include 했을 때 발생하는 문제를 미연에 방지하기 위해서이다.

#ifndef __3_1_h__
#define __3_1_h__
… … …
#endif /* ifndef __3_1_h__ */

 예를 들어, 3-1.h 헤더파일을 include한 또 다른 헤더파일인 3-2.h 파일이 존재하는데, 3-2.cpp 파일에서 다음과 같이 include 했다고 하자.

#include “3-1.h”
#include “3-2.h”

 이와 같이 했을 때, 3-2.cpp 파일에는 3-1.h 파일이 두번 include 된 것과 마찬가지가 된다. 왜냐하면 3-2.h 파일내부에서 3-1.h 파일에 대한 include가 이루어졌기 때문에 3-2.cpp 파일에는 3-1.h 파일이 두 번 include 된 것과 동일한 것이다. 이럴 경우 많은 에러가 발생한다. 변수 선언이 있다면 동일한 이름의 변수가 두 번 이상 선언된 것이고, 함수 선언이 있다면 동일한 함수가 두 번 이상 선언된 것이기 때문에 에러를 피할 수 없다.

 이때 #ifndef과 #define 그리고 #endif 구문을 사용하면 동일한 헤더파일이 두 번 include 되는 것을 방지할 수 있다. 즉, #define 의 내용이 실행되지 않았으면 #endif 구문까지를 실행하고, #define의 내용이 실행되었으면 이 구문이 실행되지 않는다. 따라서 언제나 한번만 실행이 되도록 만들 수 있는 것이다. 참고로 #ifndef(“If not define”)과 반대로 행동하는 것은 #ifdef 구문이다.

한 문자씩 버퍼에 출력하는 put 메소드

 출력 스트링 스트림에서도 put 메소드를 이용하여 버퍼에 하나의 문자식 입력할 수 있다. 간단한 예를 보면 다음과 같다.

#include <strstrea>
/* 우분투 10.04, g++-4.3.3 버전에서는 다음의 헤더파일을 사용하도록 한다.
 * #include <iostream>
 * #include <backward/strstream>
*/

using namespace std;

void main(void)
{
  ostrstream intStream;
  char intData = ‘0’;

  // 1~10 까지 숫자와 공백을 버퍼에 출력
  for(int count = 0; count < 10; count++, intData++) {
    intStream.put(intData);
    intStream.put(‘ ‘);
    if(intStream.fail()) {
      cerr << “버퍼로의 출력 에러 발생” << endl;
      return;
    }
  }

  // 마지막에 NULL 문자 입력후 화면에 출력
  intStream << ends;
  cout intStream.rdbuf() << endl;
}