티스토리 뷰
먼저 기존 for문과 비교하여 범위 기반의 for문에 대해 장점 및 단점을 보자.
장점:
- 코드가 짧고 편리하다.
- std container(vector, list, map...)와 혼합하여 사용할 수 있다.
- for문 속도차이도 크게 나지 않는다.
- 참조자(reference)와 auto를 이용한다면 더욱 빠르게 코딩할 수 있다.
단점:
- 반복 배열의 접근 Index가 없다.
- 모든 배열을 0부터 끝까지 탐색해야 한다.
사용방법:
for(type element : element_array)
왼쪽 항에는 배열 요소에 해당하는 타입과 임시 객체 변수를 적어준다.
임시 객체는 탐색하면서 인덱스 0부터 끝까지 해당하는 요소가 element_array에서 복사된다.
오른쪽 항에는 탐색할 배열 및 리스트 컨테이너를 적어주면 된다.
객체가 복사되기 때문에 element 로만 접근했을 때 변수의 주소 값이 서로 다르기 때문에
기존 배열 element_array가 가지고 있는 값들을 변경할 수 없다.
간단히 0부터 7까지 총 8개의 요소를 출력하는 코드를 적어보자
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers_vec = { 0, 1, 2, 3, 4, 5, 6, 7 };
for(int num : numbers_vec)
{
cout << num << ' ';
}
cout << '\n';
int numbers_arr[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
for(int num : numbers_arr)
{
cout << num << ' ';
}
}
두 배열(vec, arr)은 요소가 동일하며, 탐색하는 인덱스 모두 같다.
결과도 동일하다.
기본형 타입이 아닌 구조체 및 클래스로도 사용할 수 있다.
#include <iostream>
#include <vector>
using namespace std;
class Student
{
public:
int id;
string name;
Student(int _id, string _name) {
this->id = _id;
this->name = _name;
}
Student() {}
void ShowData()
{
cout << "번호: " << this->id << " 이름: " << this->name << '\n';
}
};
int main()
{
vector<Student> student_vec = {
{ 10, "찰리"},
{ 20, "제임스"},
{ 30, "미셸"}
};
for(Student stu : student_vec)
{
stu.ShowData();
}
}
배열 복사 및 요소 값의 변경:
예제 코드는 너무 단순하고 데이터 크기도 작아서 상관이 없지만
만약 복잡한 시스템이나 프로그램인 경우 오브젝트 및 객체의 크기가 클 수 있다.
크기가 큰 객체를 단순히 출력을 하거나 접근을 할 때 다른 메모리 공간에 복사하는 건 시간과 비용 부담이 크다.
참조자(reference)를 이용하면 객체가 복사되지 않고 참조하기 때문에 더 빠르게 처리할 수 있다.
타입도 일일이 적어주기보다 프로그램이 큰 경우 네임스페이스 및 상속 영향으로 타입이 복잡하고 길어질 수 있으며
C++11에서 지원하고 있는 auto 타입을 이용해 타입을 자동으로 잡아주도록 하자.
for(auto &element : element_array)
위와 같이 코드를 적으면 element 배열 요소에 해당하는 변수는 element_array에서 임시 객체를 복사하는 것이 아니고 참조되는 것이다.
참조자를 이용해서 배열 범위의 주소에서 요소에 해당하는 주소로 참조를 하기 때문에 기존 배열의 값도 변경할 수 있다.
빠른 처리 및 요소 값 변경 방지:
객체는 복사되지 않고 참조로 빠르게 접근하며 단순 값을 출력하는 것이라면 값 변경 시도 자체를 막을 수 있다.
값 변경 시도를 막는 제한자(const)와 빠르게 접근할 수 있는 참조자(reference)를 이용하는 것이다.
for(const auto& element : element_array)
const 참조자에 해당하는 객체의 함수를 호출하기 위해서는 함수에도 const 속성이 적용되어야 한다.
이젠 C++11, C++14가 메인이 되고 있다.
온라인 컴파일러 사이트에서도 C++11이 기본 컴파일러로 채택되고 있다.
길고 난해한 iterator보단 C++11에서 새로 도입된 기능을 사용하도록 하자.
만약 배열 요소 접근 Index가 필요하다면 범위 기반의 for문(range based for)은 사용할 수 없으니
이점 유의하도록 하자.