구조체를 0으로 초기화


116

다음과 같은 구조체가있는 경우 :

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

이 구조체를 0으로 초기화하는 가장 쉬운 방법은 무엇입니까? 다음으로 충분할까요?

myStruct _m1 = {0};

또는 각 멤버를 명시 적으로 0으로 초기화해야합니까?

myStruct _m2 = {0,0};

답변:


142

첫 번째 방법이 가장 쉽고 ( 타이핑이 적음 ) 작동이 보장되며 모든 멤버가 0[Ref 1] 로 설정됩니다 .
두 번째는 더 읽기 쉽습니다.

선택은 사용자 기본 설정 또는 코딩 표준에서 요구하는 항목에 따라 다릅니다.

[참조 1] 참조 C99 표준 6.7.8.21 :

중괄호로 묶인 목록의 이니셜 라이저가 집계의 요소 또는 멤버보다 적거나 알려진 크기의 배열을 초기화하는 데 사용되는 문자열 리터럴의 문자가 배열의 요소보다 적 으면 집계의 나머지는 다음과 같아야합니다. 정적 저장 기간이있는 객체와 동일하게 암시 적으로 초기화됩니다.

좋은 읽기 :
C 및 C ++ : 자동 구조의 부분 초기화


9
또한 사용하고 = {};있지만 이것이 유효한지 확실하지 않습니다.
William Entriken

15
초기화를위한 @FullDecent 빈 중괄호는 GNU 확장입니다.
a3f 2015 년

2
@ alias65536 질문은 C ++가 아닌 C 태그입니다.
a3f

3
오류가 발생했습니다. "이니셜 라이저 [-Werror = missing-braces] 주위에 중괄호가 없습니다."아마도 멤버 배열 때문일 것입니다. /
DrumM

3
@Edenia. 동의하지 않습니다. 무슨 foo = {0}뜻 인지 이미 알고 있습니다. 내가 봤다면 foo = ZERO_FULLZERO_FULL의 정의에 대해 grep해야합니다.
Andrew Bainbridge

32

데이터가 정적 또는 전역 변수 인 경우 기본적으로 0으로 채워 지므로 선언하기 만하면됩니다. myStruct _m;

데이터가 로컬 변수 또는 힙 할당 영역 인 경우 다음과 memset같이 지 웁니다 .

memset(&m, 0, sizeof(myStruct));

현재 컴파일러 (예 :의 최신 버전 gcc)는 실제로이를 매우 잘 최적화합니다. 이것은 모든 0 값 (널 포인터 및 부동 소수점 0 포함)이 모두 0 비트로 표시되는 경우에만 작동하며, 이는 내가 아는 모든 플랫폼에서 참입니다 (그러나 C 표준은 이것이 거짓 인 구현을 허용합니다. 그런 구현은 알지 못합니다) .

myStruct m = {};또는 myStruct m = {0};(첫 번째 멤버 myStruct가 스칼라가 아닌 경우에도) 또는 코드를 작성할 수 있습니다.

내 느낌은 memset로컬 구조 를 사용 하는 것이 가장 좋으며 런타임에 무언가를 수행해야한다는 사실을 더 잘 전달한다는 것입니다 (일반적으로 전역 및 정적 데이터는 런타임에 비용없이 컴파일 타임에 초기화 된 것으로 이해할 수 있음). .


7
구조체의 모든 바이트를로 설정 0하는 것이 모든 구조체 멤버를 초기화하는 것과 동일 하다는 보장은 없습니다 0. 많은 플랫폼에서 이것은 사실이지만 보편적 인 것은 아닙니다.
샌더 드 Dycker

1
예를 들어 주실 수 있나요, 샌더? 진정한 호기심. (물론, 반드시 의미하지 않는다 보편적 사실이 아니다 예외에-설명 쉬운,하지만이 있다면 ... 거기)
스티븐 피셔

2
C의 표준은 NULL 포인터를 허용한다 (또는 0 부동 소수점 수)를 모두 제로 비트보다 다른 것에 의해 메모리에 표시한다. 아주 드물고 이상한 구현이 그렇게하고 있습니다.
실레 Starynkevitch

-1, OP가 추악한 것에 대해 묻는 초기화를 찾을 수 있지만 표준에서 예상되는 것과 정확히 일치하며 모든 컴파일러에서 쉽게 최적화 할 수 있습니다. 그러면 양식 {}이 유효한 C가 아니지만 C ++에서만 사용할 수 있습니다.
옌스 Gustedt

7
@Steven : 모호하거나 오래된 플랫폼 만 생각할 수 있습니다. C FAQ에는 NULL모든 0비트 가 아닌 포인터 가있는 플랫폼 목록이 있습니다 . c-faq.com/null/machexamp.html . 그리고 플랫폼이 부동 소수점 값을 나타 내기 위해 IEEE 754를 사용하지 않고 모든 0비트 0.0값을 갖지 않는 다른 표현을 사용하고있을 가능성이 있습니다. 하지만 저는 그러한 플랫폼에 대해 알고 있습니다.
샌더 드 Dycker

19

§6.7.9 초기화 참조 :

21 중괄호로 묶인 목록의 이니셜 라이저가 집계의 요소 또는 멤버보다 적거나 알려진 크기의 배열을 초기화하는 데 사용되는 문자열 리터럴의 문자가 배열에있는 요소보다 적은 경우 집계의 나머지 정적 저장 기간을 가진 객체와 동일하게 암시 적으로 초기화됩니다.

네, 둘 다 작동합니다. C99에서는 지정된 초기화라고하는 새로운 초기화 방법도 사용할 수 있습니다.

myStruct _m1 = {.c2 = 0, .c1 = 1};

가장 주목할만한 것은 이미 C89입니다. open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139 (특정 신호 처리 대상에 대해 중요)
Tobias
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.