[c] C 프로그래밍 언어 표준에 따라 구조체를 초기화하는 방법

struct 요소를 초기화하고 선언과 초기화로 나누고 싶습니다. 이것이 내가 가진 것입니다 :

typedef struct MY_TYPE {
  bool flag;
  short int value;
  double stuff;
} MY_TYPE;

void function(void) {
  MY_TYPE a;
  ...
  a = { true, 15, 0.123 }
}

이것이 로컬 변수를 선언하고 초기화하는 방법입니까? MY_TYPE C 프로그래밍 언어 표준 (C89, C90, C99, C11 등)에 따라 입니까? 아니면 더 좋거나 최소한 작동하는 것이 있습니까?

업데이트 필자는 필요에 따라 모든 하위 요소를 설정하는 정적 초기화 요소를 갖게되었습니다.



답변

(ANSI) C99에서는 지정된 이니셜 라이저를 사용할 수 있습니다 를 하여 구조를 초기화 .

MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };

편집 : 다른 멤버는 0으로 초기화됩니다. “생략 된 필드 멤버는 정적 저장 기간을 갖는 오브젝트와 동일하게 내재적으로 초기화됩니다.” ( https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html )


답변

복합 리터럴로 할 수 있습니다 . 이 페이지에 따르면 C99에서 작동합니다 ( ANSI C 로 계산 ).

MY_TYPE a;

a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };

이니셜 라이저의 지정은 선택 사항입니다. 당신은 또한 쓸 수 있습니다 :

a = (MY_TYPE) { true,  123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };


답변

ANSI C 99에 대한 답변을 이미 받았으므로 ANSI C 89에 대한 뼈를 던질 것입니다. ANSI C 89를 사용하면 다음과 같이 구조체를 초기화 할 수 있습니다.

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = { 5, 2.2, "George" };
    return 0;
}

구조체에서 하나의 객체 / 변수를 초기화하는 순간 다른 모든 변수가 기본값으로 초기화됩니다.

구조체의 값을 초기화하지 않으면 모든 변수에 “쓰레기 값”이 포함됩니다.

행운을 빕니다!


답변

a = (MYTYPE){ true, 15, 0.123 };

C99에서 잘 될 것입니다.


답변

당신은 거의 그것을 가지고 …

MY_TYPE a = { true,15,0.123 };

‘struct initialize c’에 대한 빠른 검색 은 이것을 보여줍니다.


답변

C 프로그래밍 언어 표준 ISO / IEC 9899 : 1999 (일반적으로 C99)는 다음과 같이 지정된 이니셜 라이저 를 사용 하여 구조 또는 공용체 멤버를 초기화 할 수 있습니다.

MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };

ISO / IEC 9899 : 1999 표준의 paragraph 7섹션 6.7.8 Initialization에 다음과 같이 정의되어 있습니다.

지정자가 형식을 갖는 경우
. 식별자
는 현재 객체 (아래에 정의 됨)에 구조 또는 공용체 유형을 가져야하며 식별자는 해당 유형의 멤버 이름이어야합니다.

참고 paragraph 9동일한 섹션의 그 상태 :

명시 적으로 다르게 언급 된 경우를 제외하고,이 하위 절의 목적 상 구조 및 공용체 유형의 명명되지 않은 객체 멤버는 초기화에 참여하지 않습니다. 구조 객체의 이름이없는 멤버는 초기화 후에도 불확실한 값을 갖습니다.

그러나 GNU GCC 구현에서 생략 된 멤버는 0 또는 0과 유사한 유형에 적합한 값으로 초기화됩니다. 6.27 GNU GCC 문서의 지정된 이니셜 라이저 에 명시된대로 :

생략 된 필드 멤버는 정적 저장 기간이있는 오브젝트와 동일하게 내재적으로 초기화됩니다.

공식 블로그 게시물 C ++ Conformance Roadmap 에 따르면 Microsoft Visual C ++ 컴파일러는 버전 2013 이후 지정된 초기화 프로그램을 지원해야합니다 . 단락 Initializing unions and structs 이니셜 라이저의 MSDN의 Visual Studio 문서에서 기사는 익명의 회원들이 GNU GCC 유사 제로와 같은 적절한 값으로 초기화 제안합니다.

ISO / IEC 9899 : 1999를 대체 한 ISO / IEC 9899 : 2011 표준 (일반적으로 C11)은 섹션 아래에 지정된 이니셜 라이저를 유지합니다6.7.9 Initialization . 또한 paragraph 9변경되지 않은 상태로 유지됩니다.

ISO / IEC 9899 : 2011을 대체 한 새로운 ISO / IEC 9899 : 2018 표준 (일반적으로 C18)은 섹션 아래에 지정된 이니셜 라이저를 유지합니다 6.7.9 Initialization. 또한 paragraph 9변경되지 않은 상태로 유지됩니다.


답변

Ron Nuni가 말한 것처럼 :

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = {5, 2.2, "George"};
    return 0;
}

기억해야 할 중요한 것은 구조체에서 하나의 객체 / 변수조차 초기화 할 때 다른 모든 변수는 기본값으로 초기화됩니다.

구조체에서 값을 초기화하지 않으면 (즉, 변수를 선언 한 경우) 모두 variable.members“쓰레기 값”을 포함합니다. 선언이 로컬 인 경우에만 !

선언이 전역 또는 정적 인 경우 (이 경우와 같이) 초기화되지 않은 모든 항목은 다음과 같이 variable.members자동으로 초기화됩니다.

  • 0 정수 및 부동 소수점
  • '\0'에 대한 char물론 이것은 단지와 동일한의 ( 0char 정수 타입)
  • NULL 포인터.