다음 선언으로
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));
그것은 문자 배열 요소를 공백 문자로 초기화하는 것입니다.