제일 많이 사용 하는 STL 컨테이너 중 하나를 고르라고 하면 단연, vector가 아닐까 한다. 이 vector의 사용 법에 대해서 질문을 하려 한다.

1. vector<int> v가 주어졌다고 할 때, 아래의 줄 A와 B의 차이는 무엇인가?

A 는 범위 점검을 하여 벡터의 내부 요소에 접근 할 "수" 있다.

B 는 무조건 범위를 점검하여 벡터의 내부 요소에 접근 한다.

이 두 차이로 인하여, 무엇이 안정적인지 알 수 있을 것이다. 하지만, 안전적인게 B 방법이라 할지라도, 성능상의 이류로 A를 사용 하기도 한다. iterator 를 사용 하여..


2. 다음 코드를 고찰하라.

첫 번째

11 라인, reserve 실행시 vector의 크기가 지수적으로 증가 될 수 있기 때문에, 12라인에서의 비교가 실패할 수 잇다. 즉 v.capacity() >= 2 가 되어야 한다.

두 번째

이것은 스타일적인 문제로, assert 문 자체가 무의미 하다. 왜냐하면 표준 자체가 해당 capacity() 를 보장해 주기 때문이다.

이 두 라인은 표준 라이브러리 구현에 따라서, 오류가 생길 수도 있고 안생길 수도 있다. 그렇기 때문에 찾기 어려운 버그가 될 수 있으니, 조심 해야 한다.

착각하기 쉬운것이, reserve()는 용량을 늘려 주는 것일 뿐이지 size()를 늘려 주지 않는다. 용량은 용량일뿐 원소를 신경쓰지 말자.

이 곳에서 아무것도 출력되지 않을 것이다. 그도 그럴것이, 벡터내부에서는 아무것도 들어 있지 않기 때문이다. 하지만, 이 구문에서 여러개를 설명할 필요가 있다.

1. const 정확성을 최대한 지킬것.

왜냐하면 반복자 내부에서 iterator로 값을 변경시키지 않기 때문에


2. 반복자들을 비교할 때에는 < 대신 != 선호 할것

.. 왜냐하면 대부분의 컨테이너 반복자들이 < 를 지원하지 못하기 때문이다.(예전 생각난다. 이것 때문에 왜 에러인지 몰라 당황했었지..)


3. 후위 --. ++ 대신 전위 --, ++를 선호할 것

후위연산자는 무조건 임시객체를 생성하여 리턴하기 때문이다. 물론.. 기본자료형은 컴파일러가 알아서 고쳐 줄 수도 있으니..(믿을수 있지 ...)


4. 불필요한 재계산은 피할 것

비교 구문에서 매번 v.end() 로 비교 하게 되는데, ... 어차피 변경되지도 않을 것이라면 한번 v.end() 를 저장해 두어서 비교 하는게 더 좋을 듯 하다. 이것은 반복문의 .. 기초 최적화 방법이다.


5. endl보다 '\n' 을 선호 할것.

왜냐하면 endl 은 스트림의 내부 출력 버퍼를 비우도록 강제하기 때문이다. .. 무슨 말인지는 모르겠지만, .. 무조건 비우는 작업이 들어가기 때문에 불필요할 수 있으니, 쓰지 말고, '\n' 을 사용 하라는거 같다.


6. 루프를 직접 작성하기 보다는 알고리즘을 재사용 할 것,

수 많은 책들에서 설명되어 있다. .. 이 책에선 스타일이기 때문에, 안쓸 수도 있다고 하니, .. 음~ 경우에 따라서 무엇이 더 좋을 수도 있다고 생각 된다.


다음 코드를 봐 보자.

이 코드는 위에서 v[0] = 1 이 잘 되었을 때 잘 된다는 보장이 갖추기 때문에, ... 위에서 되냐 안되냐에 따라서 아주 위험한 코드가 될 수 있으므로, 위에서 잘 짜야 한다.

이 코드 역시 >= 를 사용 해야 하며, 불필요하다.

.. 이 코드 역시 잘 될 수도 있고 안될수도 있다. .. 위의 v[0] = 1 에 따라서.. 다르다..

이 코드의 경우, .. 문제가 생길 수도 있고 안 생길수도 있다. 그러므로 피해야 한다.

마지막 코드는 .. 위의 for 문과 동일하다!


총평

몇가지 주의해야 할것이 각인 된다. vector 을 알고서 쓰자. .. 이 책은 그 간의 Exceptional C++ 보다 좀더 충실해진것 같다.

posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요