다음 선언으로
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는 ..토큰으로 사용하지 않으므로 사용 되지 않은 것은 놀라운 일이 아닙니다.
...표기법 주위의 공백 은 본질적으로 필수입니다. 숫자에 연결되어 있으면 숫자는 부동 소수점 숫자로 해석됩니다. 예를 들어, 0...9같은 토큰 화 될 것이다 0., ., .9, 및 부동 소수점 숫자가 배열 첨자로 사용할 수 없습니다. 명명 된 상수를 사용 ...ROW-1하면 문제가 발생하지 않지만 안전한 습관에 들어가는 것이 좋습니다.
부록 :
GCC 7.3.0은 다음을 거부합니다.
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
스칼라 이니셜 라이저 1( error: braces around scalar initializer [-Werror]) 주위에 추가 중괄호 세트가 있습니다. int a = { 1 };표준에서 명시 적으로 허용하는 에서 스칼라 주위에 중괄호를 일반적으로 지정할 수 있다는 점을 감안할 때 그것이 정확하지 않습니다 . 나는 그것이 틀렸다고 확신하지 못합니다.
또한 더 나은 표기법 [0]...[9]이 모호하지 않고 다른 유효한 구문과 혼동 할 수 없으며 부동 소수점 숫자와의 혼동을 피할 수 있는지 궁금 합니다.
int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
표준위원회가 그것을 고려할까요?
답변
0으로 2d 배열을 초기화하려면 아래 방법을 사용하십시오.
int arr[n][m] = {};
참고 : 위의 방법은 0으로 초기화하는 경우에만 작동합니다.
답변
대신 벡터 배열을 사용하십시오 .
vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
답변
char grid[row][col];
memset(grid, ' ', sizeof(grid));
그것은 문자 배열 요소를 공백 문자로 초기화하는 것입니다.
