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


82

다음 선언으로

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

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

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

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


1
@ckruse : 문제는 아닙니다 어떻게 그것의, .
masoud

@MM. 내가 연결 한 스레드에 답변이 제공됩니다.
ckruse 2013 년

문제는 실제로 why and how둘 다였습니다. :)
Kraken 2013 년

@Kraken 편집 한 질문은 아마도이 질문과는 별도의 질문으로 게시되어야합니다.
Lundin 2013 년

1
@Kraken 실제로 여기 에서 그 질문을 찾았 습니다 . 내 대답 (물론!)에서 제안한대로 수행하고 GCC 확장에 의존하지 않는 것이 좋습니다.
Lundin 2013 년

답변:


126

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

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

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

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

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

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

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

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

따라서 시도하면

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


2
감사합니다. 전체 어레이를 1로 초기화하기 위해 할 수있는 일이 있습니까? 내 행과 열이 수백 개의 크기를 고려하면?
Kraken 2013 년

1
@Kraken 매크로 트릭. 이것을보십시오 .
Lundin 2014 년

int array [ROW][COLUMN] = {{0}};
저뿐입니까 아니면

@ user1794469 아니에요.
Lundin

1
@ user1794469 예, 좋습니다. 대부분의 경우 중괄호를 건너 뛰는 것은 나쁜 습관이기 때문입니다. 그러나 컴파일러는 진단을 제공 할 필요 가 없습니다 . 이 사례에 대한 좋은 / 나쁜 관행에 대해서는 이 질문에 대한 내 답변을 참조하십시오 .
Lundin

40

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

하지만이 작동 0하고 -1


17
"sizeof (array [0] [0]) * row * count"대신 "sizeof (array)"를 사용하는 것이 더 쉽습니다.
Vladyslav Savchenko

그것은 도움이 될 외에 것이 무엇인지 내게는 분명하지하지만 어떤 일정한 바이트 작동 0000하고1111
user1794469

5
포함 할 필요가 <cstring>C ++로
MTK

12

이렇게하면 첫 번째 요소 만 1로 초기화됩니다 . 다른 모든 요소는 0을 얻습니다.

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

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

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

일반 for루프는이를 빠르게 수행합니다.

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


1
@Kraken-그렇지 않습니다- 0첫 번째 값만 초기화합니다. 그런 다음 0기본적으로 나머지를 모두 초기화합니다 .
teppic 2013 년

@EricPostpischil 그래서 모든 바이트를 1로 설정하므로 32 비트 정수를 고려하면 내 value필드 memset가 1이면 행렬의 실제 값은 1이 아니지만 2^0 + 2^8 + 2^16 + 2^24?
Kraken 2013 년

@Kraken : 본질적으로 그렇습니다. memset대상의 각 바이트를 주어진 값으로 설정합니다.이 값은 int1 로 설정하는 데 작동 memset하지 않습니다. 객체의 각 바이트를 동일한 값으로 설정하지 않으려면 다중 바이트 객체의 값을 설정하는 데 사용할 수 없습니다.
Eric Postpischil 2013 년

@EricPostpischil 그래서 각각을 수동으로 초기화하는 것 외에는 할 방법이 없습니까? 내 행과 열이 수천 개라고 생각하십니까?
Kraken 2013 년

@Kraken {1}이 작동하지 않는 이유에 대한 설명을 게시했습니다. 그리고 실제로 수동 초기화 외에 다른 방법은 없습니다. 수천 개의 숫자를 입력 할 필요는 없지만 매크로 트릭이 있지만 다른 질문에 대한 주제 일 수 있습니다.
Lundin 2013 년

8

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

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

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

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

...표기법 주위의 공백 은 본질적으로 필수입니다. 숫자에 연결되어 있으면 숫자는 부동 소수점 숫자로 해석됩니다. 예를 들어, 0...9같은 토큰 화 될 것이다 0., ., .9, 및 부동 소수점 숫자가 배열 첨자로 사용할 수 없습니다. 명명 된 상수를 사용 ...ROW-1하면 문제가 발생하지 않지만 안전한 습관에 들어가는 것이 좋습니다.


부록 :

GCC 7.3.0은 다음을 거부합니다.

스칼라 이니셜 라이저 1( error: braces around scalar initializer [-Werror]) 주위에 추가 중괄호 세트가 있습니다. int a = { 1 };표준에서 명시 적으로 허용하는 에서 스칼라 주위에 중괄호를 일반적으로 지정할 수 있다는 점을 감안할 때 그것이 정확하지 않습니다 . 나는 그것이 틀렸다고 확신하지 못합니다.

또한 더 나은 표기법 [0]...[9]이 모호하지 않고 다른 유효한 구문과 혼동 할 수 없으며 부동 소수점 숫자와의 혼동을 피할 수 있는지 궁금 합니다.

표준위원회가 그것을 고려할까요?


7

0으로 2d 배열을 초기화하려면 아래 방법을 사용하십시오. int arr[n][m] = {};

참고 : 위의 방법은 0으로 초기화하는 경우에만 작동합니다.


3

대신 벡터 배열을 사용하십시오 .


3
가능하지만 OP는 C ++를 언급하지 않았습니다.
Sangeet

0

그것은 문자 배열 요소를 공백 문자로 초기화하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.