일반적으로 for문은 아래와 같은 형식으로 사용한다.
for(초기식; 조건문; 변화식){
...
}
하지만 이런방식말고도 다른 방식이 있는데, c++ 11에서는 범위 기반 for문이라는 새로운 유형의 루프를 도입하여 더 간단하고 안전하게 배열 등의 모든 요소를 반복하는 방법을 제공한다.
범위 기반 for문의 문법은 아래와 같다.
for(element_declaration : array){
statement;
}
루프는 각 array의 요소를 반복하여 element_declaration 에 선언된 변수에 현재 배열 요소의 값을 할당한다. 최상의 결과를 얻으려면 element_declaration이 배열 요소와 같은 자료형이었야한다. 그렇지 않으면 형 변환이 발생한다.
범위 기반 for문을 사용하여 배열의 모든 요소를 출력하는 예제
#include <iostream>
using namespace std;
int main(){
int arr[] = {0,1,2,3,4,5,6,7};
for(int num : arr){
cout << num << " ";
}
return 0;
}
이러면 배열안의 수가 순서대로 나온다.
루프가 실행되고 변수 num에 배열의 첫번째 요소값인 0이 할당된다. 그다음 프로그램에서는 0을 출력하는 명령문을 실행하고 다음 값이 계속해서 들어간다. 반복할 배열에 원소가 남아있지 않을 때까지 이와 같은 작업을 반복한다.
element_declaration의 자료형이 틀릴 경우 형변환이 발생한다. element_declaration은 배열 요소와 같은 자료형을 가져야하므로, auto키워드를 사용해서 c++이 자료형을 추론하도록 하는 것이 이상적이다.
#include <iostream>
using namespace std;
int main(){
int arr[] = {0,1,2,3,4,5,6,7};
for(auto num : arr){
cout << num << " ";
}
return 0;
}
위에서 본 예제들에서 element_declaration은 값으로 선언된다.
int arr[4] = {1,2,3,4};
for(auto elemnet : array){
cout << element << " ";
이렇게 되면 반복된 각 배열 요소가 element에 복사되는데, 배열요소를 복사하는 것은 비용이 많이 들 수 있다. 다행히 아래와 같은 참조를 사용할 수 있다.
int arr[4] = {1,2,3,4};
for(auto &elemnet : array){
cout << element << " ";
위 예제에서는 element는 현재 반복된 배열 요소에 대한 참조이므로 값이 복사되지 않는다. 또한 element를 수정하면 배열의 요소에 영향을 미친다.
읽기 전용으로 사용하려는 경우 elemnet를 const로 만드는 것이 좋다.
int arr[4] = {1,2,3,4};
for(const auto &elemnet : array){
cout << element << " ";
성능상의 이유로는 범위 기반 for문에선 참조 또는 const 참조를 사용하는게 좋다.
#include <iostream>
int main()
{
const int numStudents = 5;
int scores[numStudents] = { 84, 92, 76, 81, 56 };
int maxScore = 0; // keep track of our largest score
for (const auto& score: scores) // iterate over array scores, assigning each value in turn to variable score
if (score > maxScore)
maxScore = score;
std::cout << "The best score was " << maxScore << '\n';
return 0;
}
범위 기반 for문은 고정 배열뿐만이 아니라 vector, list, set, map과 같은 구조에서도 작동한다. 범위 기반 for문이 유연하다는 것을 알 수 있다.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> arr = {0,1,2,3,4,5,6,7};
for(int num : arr){
cout << num << " ";
}
return 0;
}
포인터로 변환된 배열이나 동적 배열에서 범위 기반 for 문을 사용할 수 없다. 배열의 크기를 알지 못하기 때문이다.
#include <iostream>
int sumArray(int array[]) // array is a pointer
{
int sum = 0;
for (const auto& number : array) // compile error, the size of array isn't known
sum += number;
return sum;
}
int main()
{
int array[5] = { 9, 7, 5, 3, 1 };
std::cout << sumArray(array); // array decays into a pointer here
return 0;
}
참고