그냥 게임개발자
fill() 본문
fill()
모든 값으로 초기화 할 수 있는 함수다.
0, 1, 100 등 모든 숫자로 초기화가 가능하다.
memset()
-1, 0으로만 초기화 가능
memset()을 쓰다보면 0, -1 이외의 값으로 초기화하다 틀리는 경우가 있다.
이 때 fill()을 추천한다.
여기서 보면 memset()은 0과 -1로만 초기화 가능하다보니 fill보다 시간적으로 더 빠르고 최적화 할 수 있다.
fill()
O(n)의 시간 복잡도를 가진다
fill(시작값 - first, 끝값, -last, 초기화하는 값 - val)
이런식으로 값을 초기화한다.
모든 값을 기반으로 초기화가 가능하며 [first, last]까지 val로 초기화한다.
fill()로 배열의 모든 값이 아닌 일부값을 초기화하는 경우도 있지만 보통은 전체를 초기화하는게 좋음
void fill(ForwardIterator first, ForwardIterator last, const T&val);
#include <iostream>
#include <algorithm>
using namespace std;
int a[10];
int b[10][10];
int main()
{
// 이터레이터이기에 주소의 개체를 넣어줘야 함
fill(&a[0], &a[10], 100);
for (int i = 0; i < 10; ++i)
{
cout << a[i] << " ";
}
cout << '\n';
fill (&b[0][0], &b[9][10], 2);
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
cout << b[i][j] << " ";
}
cout << '\n';
}
return 0;
}

결과먼저보고 설명하는게 편해요
일단 따라해보고 결과보고 그다음에 이해하는게 더 재밌잖아요
아니라구요?
난 그래요

fill(&a[0], &a[10], 100);
이것은 보면 알겠지만 a[0]부터 시작해 a[9]까지 100으로 초기화한다.
두번째 인자에 &a[10]은 포함하지 않는다 이전값인 a[9]를 포함한다.
fill (&b[0][0], &b[9][10], 2);
이 또한 마찬가지다.
근데 여기서 의문이가는 사람도 있을 것이다
왜 두번째 인자는 &b[9][10]이지?
&b[10][10]이지 않은가?

왜그러냐면 b[10][10]으로 초기화했으면 첫번째 배열은 0~9까지가 마지막이고 두번째 배열도 0~9까지니까
우리가 접근해야 할 인덱스는 결국 b[9][9]까지이다.
그러니 last라는 인자값에는 결국 마지막 주소의 +1을 넣어줘야 하니
b[9][10]이 되는거다.
나도 이해 안가긴했음 ㅇㅇ 처음배울때
그러면 이 fill을 주소로 인자를 넘겼으니 array to pointer decay를 활용해서 fill함수를 더 가독성있게 사용할 수 있다.
#include <iostream>
#include <algorithm>
using namespace std;
int a[10];
int b[10][10];
int main()
{
fill(a, a + 10, 100);
for (int i = 0; i < 10; ++i)
{
cout << a[i] << " ";
}
cout << '\n';
fill(&b[0][0], &b[0][0] + 10 * 10, 2);
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j< 10; ++j)
{
cout << b[i][j] << " ";
}
cout << '\n';
}
return 0;
}
하지만 2차원 이상일 경우에는 &b[0][0] + 숫자로 해야한다.
근데
왜 fill()로 전체 초기화를 해야하는가?
만약에 아래 코드와 같이 8 * 8의 정사각형으로 초기화를 시키고 싶어서 다음과 같이 초기화를 시켰는데 생각과 다르게 초기화가 될 수도 있다.
#include <iostream>
#include <algorithm>
int a[10][10];
int main()
{
fill(&a[0][0], &a[0][0] + 8 * 8, 4);
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
cout << a[i][j] << " ";
}
cout << '\n';
}
return 0;
}

ㅇㅇ 이렇다.
이상하게 된다.
보면은 fill로 초기화가 되었을 때 우리가 사용하는 2중반복문처럼 하나하나 인덱스를 접근해서 사용한다라기보단, 순차적으로 1행에 있는 요소들을 초기화한 뒤에 그 다음 2행 3행 4행 이런식으로 초기화가 일어나기 때문이다.
'C++ 나만의 복습' 카테고리의 다른 글
쓰지 말아야 할 초기화 방법 {0, } (0) | 2024.04.07 |
---|---|
memset() (0) | 2024.04.07 |
이터레이터는 일반화된 포인터인가? (0) | 2024.04.07 |
이터레이터와 포인터의 차이 (0) | 2024.04.07 |
이터레이터! (0) | 2024.04.07 |