작성자 : ["Lovelyboy^_^"]
벡터를 사용해보기 위한 기본 셋팅(앞으로 편의상 반말로 합니다.) ¶
~cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
return 0;
}
- 몇 번 써본결과 vector를 가장 자주 쓰게 된다. vector만 배워 놓으면 list나 deque같은것은 똑같이 쓸수 있다. vector를 쓰기 위한 vector 헤더를 포함시켜줘야한다. STL을 쓸라면 #include <iostream.h> 이렇게 쓰면 귀찮다. 나중에 std::cout, std:vector 이런 삽질을 해줘야 한다. 이렇게 하기 싫으면 걍 쓰던대로 using namespace std 이거 써주자.
int형 배열을 int형 벡터에 복사해 보자. ¶
~cpp
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int>::iterator VIIT; // Object형이라면 typedef vector<Object>::iterator VOIT;
int main()
{
int ar[10] = {45,12,76,43,75,32,85,32,19,98}; // Object형이라면 Object ar[10]={...};
vector<int> v(&ar[0], &ar[10]);
// Object형이라면 vector<Object> v(...);
// ar배열의 0번 원소부터 9번원소까지를
// v벡터에다가 복사 [0,10) 처음엔 폐구간
// 마지막엔 개구간이라는거 명심!
for(VIIT it = v.begin() ; it != v.end(); ++it) // 제대로 복사됐나 결과 보기
cout << *it << endl;
return 0;
}
마지막은 개구간이라는걸 명심하기 바란다.
벡터로 동적 배열 쓰기 ¶
- 아마 초보자때 누구나 하는 실수가 있을 것이다. 본인도 그랬다.--;
- 예제로 숫자를 몇개 입력받나 갯수를 입력받은 만큼, 그만큼 루프를 돌려서 숫자를 입력받는 걸 보자.
~cpp
#include <iostream>
using namespace std;
int main()
{
int num;
cin >> num;
int ar[num];
for(int i = 0 ; i < num ; ++i)
{
cout << i+1 << "번ㅤㅉㅒㅤ" << endl;
cin >> ar[i];
}
return 0;
}
- 자 어디가 틀렸을까? 공부 좀 했으면 누구나 알수 있는 삽질이지만, c++ 배운지 몇주밖에 안되었었던 나로서는 저게 왜 틀렸는지 알수가 없었다.
- 원인은 그거다. 정적 배열은 컴파일 시에 크기를 잡는다. 입력받는 부분은 컴파일 끝나고 실행할때 크기를 입력받는다. 컴파일러는 당연히 크기를 알수 없으니 에러가 나게된다. 고쳐 보자.
~cpp
#include <iostream>
using namespace std;
int main()
{
int num;
cin >> num;
int* ar = new int[num];
for(int i = 0 ; i < num ; ++i)
{
cout << i+1 << "번ㅤㅉㅒㅤ : ";
cin >> ar[i];
}
delete [] ar;
return 0;
}
- 우리가 여태까지 배운 거만 써보면 이렇게 고칠수 있다. 그 유명-_-한 동적배열이다.--; 아.. delete [] 저거 보기 싫지 않은가? c와 c++의 고질적인 문제점이 바로 저거다. 메모리 관리를 프로그래머가 해줘야 한다는거.. 자바 같은건 지가 알아서 delete 해주지만.. c나 c++에서 delete 안해주면.. X되는 꼴을 볼수 있다. (본인이 한번 경험해 봤다.) 그래서 잘 디자인된 클래스는 클래스 내에서 알아서 없애줘야 한다. 바로 vector를 쓰면 저 짓을 안해줘도 된다. 또 고쳐보자.
~cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int num;
cin >> num;
vector<int> ar(num);
for(int i = 0 ; i < ar.size() ; ++i)
{
cout << i+1 << "번ㅤㅉㅒㅤ : ";
cin >> ar[i];
}
return 0;
}
벡터로 2차원 동적 배열 쓰기 ¶
- 데블스 캠프때 유명해진 2차원 동적 배열 쓰기다.
- 파스칼 삼각형 숙제할때 데브피아에서 쓰는법 배워서 열심히 쓰다가 데블스 캠프때 재동이가 퍼뜨렸다. 1학기 내내 편해서 좋다고 써댔는데.. 지금 보면 내가 저걸 왜 쓰고 있었을까 하는 생각이 든다.
- vector로 간단히 해결이 가능하다. See also RandomWalk2/Vector로2차원동적배열만들기
- resize() 메소드는 벡터의 크기를 다시 잡아주는 역할을 한다. 잘 쓰자
Pointer를 저장하는 Container ¶
- container 에 값이 저장될때는 복사 과정이 수행된다. 그래서 값이 간단한 int, double형 에 대한 containter는 그렇게 문제가 되지 않된다.
- 덩치가 큰 자료형을 container에 저장할때 마다 복사가 수행된다면, 많은 낭비가 발생한다.
- 여기서 잡담 하나. 객체를 parameter로 넘길때도 복사가 수행되지 않는 참조를 사용하자.
~cpp Func(const Obj& obj)
- 여기서 잡담 하나. 객체를 parameter로 넘길때도 복사가 수행되지 않는 참조를 사용하자.
- 그래서 pointer만을 이용해서 저장하자. 하지만 쓸모 없는 객체는 우리가 지워줘야 한다. 포인터를 넣어줄때에는, 컨테이너가 소멸될때는 포인터들은 지워지겠지만. 그 포인터들이 가르키는 값들은 지워지지 않기 때문이다.
- 다음 예제는 pointer로 자료를 넣고, 지우는 예제이다.
~cpp #include <iostream> #include <string> #include <vector> using namespace std; class Obj { private: int a; string c; public: Obj(int n, const string& str) : a(n), c(str) {} void showMember() { cout << a << " " << c << endl; } }; typedef vector<Obj*>::iterator VOIT; int main() { vector<Obj*> v; // 포인터를 저장하는 vector // 벡터에 Obj객체들의 포인터를 넣는다. v.push_back(new Obj(1, "길동")); v.push_back(new Obj(3, "허준")); v.push_back(new Obj(5, "제마")); // 순회하면서 showMember 메소드 호출하고 for(VOIT it = v.begin() ; it != v.end() ; ++it) (*it)->showMember(); // 순회하면서 가리키는 값들을 지운다. for(it = v.begin() ; it != v.end() ; ++it) delete *it; v.clear(); return 0; }
하고 싶은 말 ¶
- 흠. 별루 어려운건 없겠지
- 이게 제가 알고 있는 STL에 대한 겁니다. 나머지나 더 자세히 알고 싶으신분은 책을 보시든지..
; MSDN을 참고하세요. 근데 이정도만 알아도.. 왠만한건 다 합니다. C++만든 그 이름 어려운 사람 BJar... Str...(
이 사람이 쓰고 싶은 기능만 쓰랬거든요--; 자바가 쓰기는 쉬워도 역시 난 c++이 좋다.
- 노파심에서 말하는 건데.. 함수로 객체를 넘길때는 꼭 참조! 참조! 입니다. 값이 안 바뀌면 꼭 const 써주시구여. 참조 안 쓰고 값 쓰면 어떻게 되는지 이펙티브 C++에 잘 나와 있습니다.(책 선전 절대 아님) 복사 생성자를 10번 넘게 호출한다는 걸로 기억함.
- C++에서는 구조체에서도 생성자가 되더군요.--;
- 구조체에서 함수역시 가능하고, constructor, destructor역시 가능합니다. 다만 class와 차이점은 상속이 안되고, 내부 필드들이 public으로 되어 있습니다. 상속이 안되서 파생하는 분제들에 관해서는 학교 C++교제 상속 부분과 virtual 함수 관련 부분의 동적 바인딩 부분을 참고 하시기 바람니다.--상민
- 구조체에서 함수역시 가능하고, constructor, destructor역시 가능합니다. 다만 class와 차이점은 상속이 안되고, 내부 필드들이 public으로 되어 있습니다. 상속이 안되서 파생하는 분제들에 관해서는 학교 C++교제 상속 부분과 virtual 함수 관련 부분의 동적 바인딩 부분을 참고 하시기 바람니다.--상민
- 글구.. 요것도 별거 아닌 팁이긴 한데.. i++과 ++i의 차이점은 다 아시죠? 근데 카운트하거나 루프를 돌때는 차이가 없다고 봐도 좋습니다. ++i가 i++보다 성능이 좋다고 하네요.(see also i++VS++i 이건 뭐..~ 맘대로 하세요^^
- 02 여러분 c++공부 열심히 해요~
STL/vector










