development

하나의 값으로 전체 2D 배열 초기화

big-blog 2020. 11. 17. 20:02
반응형

하나의 값으로 전체 2D 배열 초기화


다음 선언으로

int array[ROW][COLUMN]={0};

나는 모두 0으로 배열을 얻지 만 다음은 다음과 같습니다.

int array[ROW][COLUMN]={1};

하나의 값으로 배열을 얻지 못합니다. 기본값은 여전히 ​​0입니다.

이 동작이 왜 그리고 어떻게 모두 1로 초기화 할 수 있습니까?

편집 : memset값을 1로 사용하면 각 바이트가 1로 설정되므로 각 배열 셀의 실제 값이 1이 아니라 16843009. 1로 설정하려면 어떻게합니까?


이 동작 은 "모든 항목을 하나로 설정"을 의미 int array [ROW][COLUMN] = {1};하지 않기 때문에 발생 합니다. 이것이 어떻게 작동하는지 단계별로 설명하겠습니다.

배열을 초기화하는 명시적이고 지나치게 명확한 방법은 다음과 같습니다.

#define ROW 2
#define COLUMN 2

int array [ROW][COLUMN] =
{
  {0, 0},
  {0, 0}
};

그러나 C를 사용하면 배열 (또는 구조체 / 유니온)의 일부 항목을 생략 할 수 있습니다. 예를 들어 다음과 같이 작성할 수 있습니다.

int array [ROW][COLUMN] =
{
  {1, 2}
};

즉, 첫 번째 요소를 1과 2로 초기화하고 나머지 요소는 "정적 저장 기간이있는 것처럼"초기화합니다. C에는 프로그래머가 명시 적으로 초기화하지 않은 정적 저장 기간의 모든 개체를 0으로 설정해야한다는 규칙이 있습니다.

따라서 위의 예에서 첫 번째 행은 명시적인 값을 제공하지 않았기 때문에 1,2로 설정되고 다음 행은 0,0으로 설정됩니다.

다음으로 C에는 느슨한 중괄호 스타일을 허용하는 규칙이 있습니다. 첫 번째 예는 다음과 같이 작성할 수 있습니다.

int array [ROW][COLUMN] = {0, 0, 0, 0};

물론 이것은 형편없는 스타일이지만 읽고 이해하기가 더 어렵습니다. 하지만이 규칙은 편리합니다.

int array [ROW][COLUMN] = {0};

즉, "첫 번째 행의 첫 번째 열을 0으로 초기화하고 다른 모든 항목은 정적 저장 기간이있는 것처럼 초기화합니다. 즉, 0으로 설정합니다."

따라서 시도하면

int array [ROW][COLUMN] = {1};

이는 "첫 번째 행의 첫 번째 열을 1로 초기화하고 다른 모든 항목을 0으로 설정"을 의미합니다.


배열을 초기화하려면 -1다음을 사용할 수 있습니다.

memset(array, -1, sizeof(array[0][0]) * row * count)

하지만이 작동 0하고 -1


int array[ROW][COLUMN]={1};

이것은 첫 번째 요소 1로 초기화합니다 . 다른 모든 요소는 0을 얻습니다.

첫 번째 인스턴스에서는 동일한 작업을 수행합니다. 첫 번째 요소를 0으로 초기화하고 나머지는 기본적으로 0으로 초기화합니다.

이유는 간단합니다. 배열의 경우 컴파일러는 지정하지 않은 모든 값을 0으로 초기화합니다.

A를 char배열 당신이 사용할 수있는 memset모든 바이트를 설정할 수 있지만, 이것은 일반적으로 작동하지 않습니다 int(0 그것의 미세하지만) 배열입니다.

일반적인 for루프는이 작업을 빠르게 수행합니다.

for (int i = 0; i < ROW; i++)
  for (int j = 0; j < COLUMN; j++)
    array[i][j] = 1;

또는 더 빠름 (컴파일러에 따라 다름)

for (int i = 0; i < ROW*COLUMN; i++)
  *((int*)a + i) = 1;

GCC에는 컨텍스트에 매우 유용한 지정된 이니셜 라이저 표기법에 대한 확장이 있습니다. 또한 clang주석없이 허용됩니다 (부분적으로 GCC와 호환되기 때문에).

확장 표기법을 사용 ...하면 다음 값으로 초기화 할 요소 범위를 지정할 수 있습니다. 예를 들면 :

#include <stdio.h>

enum { ROW = 5, COLUMN = 10 };

int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } };

int main(void)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLUMN; j++)
            printf("%2d", array[i][j]);
        putchar('\n');
    }
    return 0;
}

결과는 당연히 다음과 같습니다.

 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1

Fortran 66 (Fortran IV)에는 배열의 이니셜 라이저에 대한 반복 횟수가 있습니다. 지정된 이니셜 라이저가 언어에 추가되었을 때 C가 그것들을 얻지 못했다는 것이 항상 이상하게 느껴졌습니다. 그리고 Pascal은 0..9표기법을 사용하여 0에서 9까지 범위를 지정하지만 C는 ..토큰으로 사용하지 않으므로 사용 되지 않은 것은 놀라운 일이 아닙니다.

Note that the spaces around the ... notation are essentially mandatory; if they're attached to numbers, then the number is interpreted as a floating point number. For example, 0...9 would be tokenized as 0., ., .9, and floating point numbers aren't allowed as array subscripts. With the named constants, ...ROW-1 would not cause trouble, but it is better to get into the safe habits.


Addenda:

I note in passing that GCC 7.3.0 rejects:

int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };

where there's an extra set of braces around the scalar initializer 1 (error: braces around scalar initializer [-Werror]). I'm not sure that's correct given that you can normally specify braces around a scalar in int a = { 1 };, which is explicitly allowed by the standard. I'm not certain it's incorrect, either.

I also wonder if a better notation would be [0]...[9] — that is unambiguous, cannot be confused with any other valid syntax, and avoids confusion with floating point numbers.

int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };

Maybe the standards committee would consider that?


Use vector array instead:

vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));

참고URL : https://stackoverflow.com/questions/15520880/initializing-entire-2d-array-with-one-value

반응형