6.1 이번 장에서 만들어 볼 프로그램
6.2 객체 배열
: 객체들이 모여 있는 컨테이너
#include <iostream>
#include <stdlib.h>
using namespace std;
class Circle {
public:
int x, y;
int radius;
Circle() {
x = 0;
y = 0;
radius = 0;
}
Circle(int _x, int _y, int r) {
x = _x;
y = _y;
radius = r;
}
void print() {
cout << "반지름: " << radius << " @(" << x << ", " << y << ")" << endl;
}
};
int main() {
Circle objArray[10]; // 객체 배열
srand(time(NULL));
for (Circle& c : objArray) {
c.x = rand() % 500;
c.y = rand() % 500;
c.radius = rand() % 100;
}
for (Circle& c : objArray) {
c.print();
}
return 0;
}
여러 권의 책을 저장해보자
#include <iostream>
#include <string>
using namespace std;
class Book {
public:
string title;
int price;
Book(string t, int p) {
title = t;
price = p;
}
void print() {
cout << "제목: " << title << ", 가격: " << price << endl;
}
};
int main() {
// 객체 배열
Book books[2] = {
Book("어서와 C++", 30000),
Book("어서와 C", 22000)
};
cout << "소장하고 있는 책 정보" << endl;
cout << "================================" << endl;
for (Book& b : books)
b.print();
cout << "================================" << endl;
return 0;
}
6.3 벡터
이제까지 우리가 학습한 배열은 정적 배열이다. 즉, 컴파일 시간에 배열의 크기가 결정되고, 더 이상 크기의 변경은 불가능하다.
C++에서는 실행 시간에 크기를 변경할 수 있는 동적 배열(dynamic array)도 제공한다. 이것은 벡터(vector)라고 불리며, 라이브러리로 제공된다.
/* 벡터 선언 */
vector<int> scores(10); // 배열의 자료형, 배열의 이름, 배열의 크기
▶ push_back()과 pop_back()
: 정적 배열을 사용하는데 가장 문제점은 저장되는 데이터의 개수를 미리 알지 못한다는 것이다.
예를 들어, 성적 평균을 계산하는 프로그램에서도 학원생들이 수시로 등록하거나 취소하기 때문에 학원생이 몇 명인지 알 수 없다고 하자.
- push_back(): 공백 벡터에서 시작하여서 성적이 하나씩 추가될 때마다 벡터의 크기를 확대한다.
#include <vector>
#include <iostream>
using namespace std;
int main(void) {
vector<int> v1;
// push_back
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
cout << "v1 = ";
for (auto& v : v1)
cout << v << " ";
return 0;
}
- pop_back(): 벡터의 끝에서 요소를 제거하고, 벡터의 크기를 하나 감소시킨다. 한가지 주의할 점은, pop_back()은 요소를 반환하지 않는다. 따라서 삭제하기 전에 미리 삭제할 요소를 다른 곳에 저장하여야 한다.
#include <vector>
#include <iostream>
using namespace std;
int main(void) {
vector<int> v;
// push_pack()
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
cout << "현재의 v = ";
for (auto& e : v)
cout << e << " ";
cout << endl;
cout << "삭제 요소 = ";
// 벡터가 공백이 될 때까지 pop_back() 호출
while (v.empty() != true) {
cout << v.back() << " ";
v.pop_back();
}
cout << endl;
}
▶ 벡터에서 요소의 위치
: 벡터에서 요소의 위치는 반복자(iterator)를 이용하여 표시한다.
▶ 중간에서 삭제하는 방법
: 중간에서 삭제하려면 삭제하려는 요소의 인덱스를 알아야 한다.
- v.erase()
// 인덱스가 i인 요소 삭제
v.erase(v.begin()+i);
▶ 벡터와 연산자
▶ 문자열을 저장해보자.
: 객체 배열은 전통적인 방식으로 만들 수도 있지만, 벡터(vector 클래스)를 이용하여 동적인 객체 배열을 만들 수도 있다.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main(void) {
vector<string> v;
v.push_back("MILK");
v.push_back("BREAD");
v.push_back("BUTTER");
for (auto& c : v)
cout << c << " ";
cout << endl;
return 0;
}
▶ Circle 객체를 저장해보자.
#include <iostream>
#include <vector>
using namespace std;
class Circle {
public:
int x, y;
int radius;
Circle() {
x = 0;
y = 0;
radius = 0;
}
Circle(int _x, int _y, int r) {
x = _x;
y = _y;
radius = r;
}
void print() {
cout << "반지름: " << radius << " @(" << x << ", " << y << ")" << endl;
}
};
int main() {
vector<Circle> objArray; // Circle 객체 저장
for (int i = 0; i < 10; i++) {
Circle obj{ rand() % 300, rand() % 300, rand() % 100 };
objArray.push_back(obj); // obj을 push_back
}
for (Circle c : objArray)
c.print();
return 0;
}
▶ 벡터와 알고리즘
: 우리가 벡터를 사용하는 중요한 이유 중의 하나는 편리한 STL 알고리즘을 사용할 수 있기 때문이다.
예를 들어, 우리는 벡터 안의 요소들을 어떤 기준에 의하여 정렬시킬 수 있다.
- bool compare()
- sort()
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
class Person {
public:
string name;
int age;
Person(string n, int a) {
name = n;
age = a;
}
string get_name() {
return name;
}
int get_age() {
return age;
}
void print() {
cout << name << " " << age << endl;
}
};
// Person 객체들을 나이순으로 정렬하는 비교 함수
bool compare(Person& p, Person& q) {
return p.get_age() < q.get_age();
}
int main() {
vector<Person> list;
list.push_back(Person("Kim", 30));
list.push_back(Person("Park", 22));
list.push_back(Person("Lee", 26));
// sort(정렬)
sort(list.begin(), list.end(), compare);
for (auto& l : list)
l.print();
return 0;
}
성적 평균 계산하기
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> score;
int sum = 0;
int i = 0;
while (1) {
int input;
cout << "성적을 입력하시오(종료는 -1) : ";
cin >> input;
if (input == -1)
break;
score.push_back(input);
i++;
}
for (auto& e : score)
sum += e;
cout << "성적 평균=" << sum / i << endl;
return 0;
}
영화 정보 저장
#include <iostream>
#include <vector>
using namespace std;
class Movie {
public:
string title;
double score;
Movie(string t, double s) {
title = t;
score = s;
}
void print() {
cout << title << ": " << score << endl;
}
};
int main() {
vector<Movie> myMovie;
myMovie.push_back(Movie("타이타닉", 9.9));
myMovie.push_back(Movie("바람과 함께 사라지다", 9.6));
myMovie.push_back(Movie("터미네이터", 9.7));
for (auto& e : myMovie)
e.print();
return 0;
}
6.4 array 클래스
- vector: 생성과 소멸을 하는데 상당한 시간이 소요된다. 따라서 vector의 장점이 많지만 성능때문에 기존의 배열을 사용하는 경우도 많다.
이 문제를 해결하기 위해 c++11에서는 std::array를 새롭게 제시하였다.
array 클래스를 사용하면 벡터의 장점과 기존 배열의 성능을 동시에 누릴 수 있다.
#include <iostream>
#include <array>
using namespace std;
int main() {
array<int, 3> list{1, 2, 3};
for (int i = 0; i < list.size(); i++)
list[i]++;
for (auto& e : list)
cout << e << " ";
cout << endl;
return 0;
}
- size(): 배열의 크기
- fill(): 배열의 모든 원소를 동일한 값으로 채운다.
- empty(): 배열이 비어있는지 검사한다.
- at(): 배열의 요소에 접근할 때 사용된다. ([] 기호를 사용해도 됨)
- front(): 배열의 첫 번째 요소
- back(): 배열의 마지막 요소
'Programming > C++' 카테고리의 다른 글
[C++] 8. 포인터와 동적객체 생성 (1) | 2024.02.12 |
---|---|
[어서와 C++는 처음이지!] CH6 Exercise (1) | 2024.01.30 |
[어서와 C++는 처음이지!] CH5 Exercise (0) | 2024.01.29 |
[C++] 5. 생성자와 접근제어 (0) | 2024.01.29 |
[어서와 C++는 처음이지!] CH4 Exercise (1) | 2024.01.29 |