Programming

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

procodes 2020. 2. 18. 22:55
반응형

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_TYPEC 프로그래밍 언어 표준 (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 포인터.

void function(void) {
  MY_TYPE a;
  a.flag = true;
  a.value = 15;
  a.stuff = 0.123;
}

MS가 C99로 업데이트되지 않은 경우 MY_TYPE a = {true, 15,0.123};


구조체를 초기화하는 다른 방법을 찾았습니다.

구조체 :

typedef struct test {
    int num;
    char* str;
} test;

초기화 :

test tt = {
    num: 42,
    str: "nice"
};

GCC 문서에 따르면이 구문은 GCC 2.5 이후더 이상 사용되지 않습니다 .


나는이 답변들 중 어느 것도 마음에 들지 않아서 나 자신을 만들었다. 이것이 ANSI C인지 아닌지는 모르겠습니다. 기본 모드에서는 GCC 4.2.1입니다. 브라케팅을 기억할 수 없으므로 데이터의 하위 집합으로 시작하고 종료 될 때까지 컴파일러 오류 메시지와 싸우십시오. 가독성이 최우선입니다

    // in a header:
    typedef unsigned char uchar;

    struct fields {
      uchar num;
      uchar lbl[35];
    };

    // in an actual c file (I have 2 in this case)
    struct fields labels[] = {
      {0,"Package"},
      {1,"Version"},
      {2,"Apport"},
      {3,"Architecture"},
      {4,"Bugs"},
      {5,"Description-md5"},
      {6,"Essential"},
      {7,"Filename"},
      {8,"Ghc-Package"},
      {9,"Gstreamer-Version"},
      {10,"Homepage"},
      {11,"Installed-Size"},
      {12,"MD5sum"},
      {13,"Maintainer"},
      {14,"Modaliases"},
      {15,"Multi-Arch"},
      {16,"Npp-Description"},
      {17,"Npp-File"},
      {18,"Npp-Name"},
      {19,"Origin"}
    };

데이터가 탭으로 구분 된 파일로 시작되어 다른 것으로 마사지하기 위해 검색을 대체 할 수 있습니다. 네, 데비안입니다. 따라서 {}의 외부 쌍 하나 (배열을 나타냄)와 각 구조체 내부에 다른 쌍이 있습니다. 사이에 쉼표가 있습니다. 헤더에 물건을 넣는 것이 꼭 필요한 것은 아니지만 내 구조체에 약 50 개의 항목이 있으므로 별도의 파일에 저장하여 코드에서 혼란을 피하고 교체하기가 더 쉽습니다.


C의 구조는 다음과 같이 선언하고 초기화 할 수 있습니다.

typedef struct book
{
    char title[10];
    char author[10];
    float price;
} book;

int main() {
    book b1={"DS", "Ajay", 250.0};

    printf("%s \t %s \t %f", b1.title, b1.author, b1.price);

    return 0;
}

집계 유형 초기화에 대한 Microsoft Visual Studio 2015 설명서를 읽었 {...}지만 여기에서 초기화하는 모든 형태에 대해 설명하지만``designator ''라는 도트로 초기화하는 것은 언급되지 않았습니다. 또한 작동하지 않습니다.

C99 표준 장 6.7.8 초기화는 지정자의 가능성을 설명하지만 복잡한 구조에 대해서는 분명하지 않습니다. PDF로 C99 표준 .

내 마음에, 그것은 더 나을 수 있습니다

  1. = {0};모든 정적 데이터에 -initialization을 사용하십시오 . 기계 코드에 대한 노력이 적습니다.
  2. 예를 들어 매크로를 사용하여 초기화

    typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}

매크로를 조정할 수 있으며 인수 목록은 변경된 구조체 내용과 독립적 일 수 있습니다. 적은 수의 요소를 초기화해야하는 경우에 적합합니다. 중첩 된 구조체에도 적합합니다. 3. 간단한 형태는 다음과 같습니다. 서브 루틴에서 초기화합니다.

void init_MyStruct(MyStruct* thiz, int a, int b) {
  thiz->a = a; thiz->b = b; }

이 루틴은 C에서 ObjectOriented처럼 보입니다. C ++로 컴파일 thiz하지 말고 사용하십시오 this!

MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);

구조체를 초기화하는 좋은 방법을 찾고 있었고 아래 (C99)를 사용해야합니다. 이를 통해 일반 유형과 동일한 방식으로 단일 구조 또는 구조 배열을 초기화 할 수 있습니다.

typedef struct {
    char *str;
    size_t len;
    jsmntok_t *tok;
    int tsz;
} jsmn_ts;

#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}

이것은 코드에서 다음과 같이 사용될 수 있습니다.

jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */

jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
                                                    first 2 structs in the array */

참고 URL : https://stackoverflow.com/questions/330793/how-to-initialize-a-struct-in-accordance-with-c-programming-language-standards



반응형