Game Develop

[C++] C++에서 배열초기화하기 본문

C++/C++

[C++] C++에서 배열초기화하기

MaxLevel 2022. 9. 8. 11:45

보통 int형 배열을 선언하고 0으로 초기화하려하면 아래와 같이 코드를 작성한다.

 

1. int arr[200] = {0};

2. memset(arr,0,200);

 

두 방법의 차이는 뭘까?

정답은 거의 동일하다이다. Visual Studio 2017 기준으로, 컴파일러는 두 방법 다 내부적으로 _memset을 호출해서 해당 작업을 수행한다.

 

0으로 말고, 다른값으로 초기화하고 싶으면 아래와 같은 함수를 사용하자.

fill_n (arr,200,-1000); // arr을 -1000으로 초기화. 

 

2차원배열을 초기화하고 싶다면 아래와 같이 사용하면 된다.

int arr[200][200];

fill(&arr[0][0], &arr[199][200], -1000) // 2차원배열 arr을 -1000으로 초기화.

 

보다시피 두번째 매개변수에서는 행부분에 -1값을 해줘야 한다.

 

---------------------------------------------------------------------------------------------------------------------------------

 

만약에 배열을 매우 큰 수로 초기화하고 싶을 경우, memset으로도 초기화가 가능하다.

일반적으로 memset은 0으로 초기화할때만 사용하라..라고 되어있지만, 아래와 같이 초기화가 가능하다.

 

int graph[201][201] = {0};
memset(graph, 0x3f, sizeof(graph)); // 16진수 두개로 초기화.

 

memset은 바이트 단위로 초기화를 시켜주는 함수이다.

그리고 1바이트는 8비트이고, 16진수의 한자리는 4비트다. 즉, 16진수 두개는 1바이트이다.

그래서 저렇게 초기화가 가능하다. 초기화시킬 배열자체는 int배열이니까 배열원소 하나당 16진수 3f가 4개가 들어가게된다. 결국 graph의 각 원소는 0x3f3f3f3f값을 지니게 되는데, 10진수로 바꾸면 1061109567 이 된다. 

3f 이상의값을 해버리면 오버플로우가 날 수 있으니 3f가 적정선이다. 

 

관련되서 조심할 점으로, 다익스트라나 플로이드와샬처럼 초기에 큰값으로 초기화시켜놓고 그 후 로직을 통해 값을 업데이트 시켜야할 경우 두 값을 더하고 비교하고 막 이런 과정을 거칠텐데, 이런 비교를 위한 변수는 long long으로 해놔야한다.위처럼 원소하나가 10억가량 되버리면 중간에 가중치 3개이상을 더해야하는 과정이 있다면 30억을 넘어버린다

즉, int형 범위를 넘어버리니까 long long으로 담아놓아야한다.

 

 

 

결론.

1. 배열을 특정값으로 초기화하려면, 1차원배열은 fill_n, 2차원 배열은 fill 함수로 초기화하자.

2. 비교를 위한 그저 큰수로초기화하려면 memset으로도 가능하다.(1차든 2차든 가능.)

    성능이 제일 좋으니, 써먹을 수 있으면 써먹어보자.