For-each 반복문 (ranged-based for statement) in C++11 본문
For - each 반복문
for 문 for statement
for 문 for statement C++에서 가장 많이 사용하는 반복문은 for 문이다. for 문은 각 반복 후에 루프 변수의 값을 쉽게 정의, 초기화 및 변경 할 수 있기 때문에 반복해야 하는 횟수를 정확히 알고 있을
hyoniidaaa.tistory.com
배열과 반복문
배열과 반복문(Array and Loop) 이전 포스트에서 배열 인덱스는 상수 값이 아니어도 된다는 것을 알았다. 인덱스는 변수일 수도 있다. 즉, 루프 변수를 사용하여 배열의 모든 요소를 반복하고 일부
hyoniidaaa.tistory.com
지금까지 array를 for문으로 돌릴 때 구현할 양이 많아서 부담스러웠다.
훨씬 간단해진 for-each 문에 대해서 설명드리겠다.
C++11에서는 범위 기반 for 문(ranged-based for statement)이라는 새로운 유형의 루프를 도입하여
더 간단하고 안전하게 배열 등의 모든 요소를 반복하는 방법을 제공한다.
Ranged-based for loops
범위 기반 for 문의 문법은 다음과 같다.
for (element_declaration : array)
statement;
루프는 각 array의 요소를 반복하여 element_declaration에 선언된 변수에 현재 배열 요소의 값을 할당한다.
최상의 결과를 얻으려면 element_declaration이 배열 요소와 같은 자료형이어야 한다.
그렇지 않으면 형 변환이 발생한다.
예를 들어보자
이제까지는 for문을 써서 배열 안에 있는 원소들을 출력할 때 보통 이런 식으로 코딩해왔다.
이 원소들이 몇개인지 세는 건 귀찮다.
이럴 때 for-each를 사용해보자
이 number에는 fibonacci[ ]에 있는 각 원소들이 한번씩 들어오게 된다.
그 다음 array 이름을 써줘야 한다.
실행시켜보면
이전에 쓰던 for문에 비해 아주 코드가 간결해졌다.
이번에는 값도 바꿔보자
원소의 값들을 모두 10으로 바꾸는 코드를 작성해 보자
저 상태에서 출력해보면
값이 바뀌지 않고 그대로 남아있다.
어떻게 해야 하냐면 int 뒤에 레퍼런스를 붙여주면 된다.
붙여주면
fibonacci가 const라서 문제가 생겼다.
그렇다면 const를 없애보자.
fibonacci에 const를 없애고 number에 레퍼런스를 붙여주니까 10이 잘 들어갔다.
Ranged-based for loops and the auto keyword
element_declaration 은 배열 요소와 같은 자료형을 가져야 하므로,
auto 키워드를 사용해서 C++이 자료형을 추론하도록 하는 것이 이상적이다.
보통 여기에 auto를 넣는다.
auto를 넣으면 int가 자동으로 들어와서 결정된다.
number에 마우스를 가져다대면 int가 나온다.
fibonacci가 int의 array이니까 자동으로 int가 결정되는 것이다.
보통 이렇게 auto를 많이 쓴다.
여기서는 값을 바꿔주려고 하는 부분이니까 레퍼런스로 하는 건 괜찮다.
그런데 number는 현재 반복된 배열 요소에 대한 참조이므로 값이 복사되지 않는다.
또한, number를 수정하면 배열의 요소에 영향을 미친다.
읽기 전용으로 사용하려는 경우 number를 const로 만드는 것이 좋다.
여기서 const와 &를 넣어서
for (const auto &number : fibonacci) 이렇게들 많이 쓴다.
이렇게 하면 이 for-loop 에서는 number 값을 바꾸지 않겠다는 의지를 보여주고 있는 것이다.
성능상의 이유로 for each 문에서는 참조 또는 const 참조를 사용하는 것이 좋다.
이번에는 * 곱하기를 붙여보았다.
각 원소들에 10씩 곱해진 것을 확인할 수 있다.
이전 포스팅에서 주어진 숫자중에 가장 큰 숫자를 찾는 프로그램을 만들었었다.
배열과 반복문
배열과 반복문(Array and Loop) 이전 포스트에서 배열 인덱스는 상수 값이 아니어도 된다는 것을 알았다. 인덱스는 변수일 수도 있다. 즉, 루프 변수를 사용하여 배열의 모든 요소를 반복하고 일부
hyoniidaaa.tistory.com
이번에는 for-each를 사용해서 다시 만들어보자.
이렇게 하다가 생각이 잘 안날 때는 구글링 ㄱㄱ
이렇게 하면 "둘 중 더 큰 것을 대입해라"라는 의미이다.
출력해보면
혹시 순서에 상관있나 싶은 분은 중간에 숫자 한개 더 넣어보면 된다.
가장 큰 숫자를 잘 찾고 있다.
Ranged-based for loops doesn't work with pointers to an array
포인터로 변환된 배열에서 for each 루프를 사용할 수 없다.
배열의 크기를 알지 못하기 때문이다.
#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;
}
마찬가지로, 동적 배열은 같은 이유로 for each 루프 못 쓴다.
Ranges-based for loops and non-arrays
for each 루프는 고정 배열뿐만 아니라 std::vector, std::list, std::set, std::map과 같은 구조에서도 작동한다.
방금 언급한 것들을 아직 배우지 않았으므로 무엇인지 몰라도 걱정하지 않아도 된다.
지금은 for each 문이 유연하다는 것만 기억하면 된다.
맛보기로 예제 하나만 보자
array를 동적 할당하면 for-each를 사용할 수 없다.
한계가 있으니 단점이라고 생각할 수 있다.
대신 그것보다 더 좋은 것을 사용할 수 있다.
int [ ] 대신에 vector를 쓸 수 있다.
이렇게 하면 fibonacci가 vector로 선언된다.
그리고 이 vector는 동적할당 배열을 아주 편하게 사용할 수 있도록 std에 들어있는 기능이다.
예전에는 array를 만들어서 썼는데 이제는 vector를 쓰면 훨씬 작업 속도가 빠르다.
아무튼 이 상태에서 작동시켜보면 결과도 똑같이 잘 나온다.
그러니까 동적할당 배열 대신에 vector를 쓸 수 있게 된 것이다.
vector를 쓰면 훨씬 편해진다.
vector에 대해서는 추후 자세히 포스팅하겠다. 😉
'💘 C++ > 행렬, 문자열, 포인터, 참조' 카테고리의 다른 글
이중 포인터와 동적 다차원 배열 (Pointers to pointers and dynamic multidimensional arrays) (0) | 2022.07.22 |
---|---|
보이드 포인터 (void pointer) (0) | 2022.07.21 |
포인터와 참조의 멤버 선택 Member selection with pointers and references (0) | 2022.07.20 |
참조와 Const (Reference and Const) (0) | 2022.07.19 |
참조 변수 (Reference Variable) (0) | 2022.07.17 |