programing

C 구조를 선언하는 구문론적으로 적절한 방법은 무엇입니까?

muds 2023. 10. 23. 22:10
반응형

C 구조를 선언하는 구문론적으로 적절한 방법은 무엇입니까?

전에 C structs가 여러 가지 다른 방법으로 선언된 것을 본 적이 있습니다.그것은 왜 그리고 만일 무엇이 있다면, 각자가 하는 일이 다릅니까?

예를 들어,

struct foo {
  short a;
  int b;
  float c;
};

typedef struct {
  short d;
  int e;
  float f;
} bar;

typedef struct _baz {
  short a;
  int b;
  float c;
} baz;

int main (int argc, char const *argv[])
{
  struct foo a;
  bar b;
  baz c;

  return 0;
}

명백한 차이는 당신이 보여주는 것처럼main:

struct foo a;
bar b;
baz c;

첫번째 선언은...typedefedstruct그리고 필요합니다.struct사용할 키워드.두번째는.typedef익명의struct, 그래서 우리는 그를 사용합니다.typedefname. 세 번째는 첫 번째와 두 번째를 모두 결합합니다. 당신의 예는 다음을 사용합니다.baz(편리하게 짧지만) 쉽게 사용할 수 있습니다.struct _baz같은 취지로

업데이트: larsmans의 답변은 적어도 사용해야 하는 더 일반적인 경우를 언급합니다.struct x { }연결된 목록을 만들기 위해서 입니다.두 번째 경우는 여기서 불가능할 것입니다(정신을 버리고 사용하지 않는 한).void *대신).struct익명이고, 그리고.typedef다음이 될 때까지 일어나지 않습니다.struct정의되어 있으며, 에 대한 (유형 안전) 포인터를 만들 방법이 없습니다.struct타이핑을 합니다.이 용도로는 첫 번째 버전이 괜찮지만, 제 경험으로는 세 번째 버전이 일반적으로 더 좋습니다.그에 대한 평판을 좀 주세요.

더 미묘한 차이는 네임스페이스 배치에 있습니다.주식회사,struct태그는 다른 이름과 별도의 네임스페이스에 배치되지만,typedef이름은 그렇지 않습니다.그렇다면 다음은 합법적입니다.

struct test {
  // contents
};

struct test *test() {
  // contents
}

그러나 다음은 그렇지 않습니다, 왜냐하면 이름이 무엇인지 애매할 것이기 때문입니다.test다음과 같습니다.

typedef struct {
  // contents
} test;

test *test() {
  // contents
}

typedef는 이름을 더 짧게(항상 플러스) 만들지만 변수 및 함수와 동일한 네임스페이스에 넣습니다.보통 이것은 문제가 되지 않지만, 단순한 단축을 넘어 미묘한 차이입니다.

그것은 주로 개인적인 선호의 문제입니다.나는 새로운 타입에게 대문자로 시작하는 이름을 주고 생략하는 것을 좋아합니다.struct, 그래서 주로 글을 씁니다.typedef struct { ... } Foo. 그러면 글을 쓸 수 없다는 뜻입니다.struct Foo.

예외는 다음과 같은 경우입니다.struct에는 고유한 유형에 대한 포인터가 포함되어 있습니다.

typedef struct Node {
    // ...
    struct Node *next;
} Node;

이 경우에는 다음과 같이 선언해야 합니다.struct Nodetype, since thetypedef범위 내에 있지 않습니다.struct정의.두 이름이 동일할 수도 있습니다. (밑줄 규칙이 어디에서 시작되었는지는 잘 모르겠지만, 오래된 C 컴파일러는 처리할 수 없었던 것 같습니다.typedef struct X X;).

당신이 사용하는 모든 것은 구문론적으로 정확합니다.나는 다음과 같은 용도를 선호합니다.

 /* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
  short a;
  int b;
  foo* next;
};

이를 통해 쉽게 사용할 수 있음을 확인합니다.typedef이미 그 선언 안에struct그 자체로, 그리고 그것조차도.struct상호간에 서로를 참조하는 것입니다.

이러한 혼란은 일부 선언문이 사실상 3개의 C 구성까지 선언하고 있기 때문에 발생합니다.다음과 같은 차이점을 염두에 두어야 합니다.

  1. 디에프 선언을 입력하면,
  2. 구조적 정의,
  3. 구조 선언.

그것들은 모두 매우 다른 C 구조입니다.이들은 모두 다른 일을 하지만, 원한다면 이들을 하나의 복합 구조물로 결합할 수도 있습니다.

각 선언문을 차례로 살펴보도록 하겠습니다.


struct foo {
  short a;
  int b;
  float c;
};

여기서는 가장 기본적인 구조 정의 구문을 사용합니다.우리는 C타입을 정의하고 있고 이름을 부여하고 있습니다.foo태그 네임스페이스에 저장됩니다.나중에 다음 구문을 사용하여 해당 유형의 변수를 선언하는 데 사용할 수 있습니다.

struct foo myFoo;  // Declare a struct variable of type foo.

이 다음 선언은 형식에 글로벌 네임스페이스의 다른 이름(alias)을 제공합니다.앞의 기본 선언문을 사용하여 구성 요소로 나누어 보겠습니다.

typedef struct foo bar;   // Declare bar as a variable type, the alias of foo.

bar myBar;         // No need for the "struct" keyword

이제 "foo"를 구조의 정의와 voila로 대체하세요!

typedef struct {
  short d;    
  int e;
  float f;
} bar;

typedef struct _baz {
  short a;
  int b;
  float c;
} baz;

위 구문은 다음과 같은 선언 순서와 같습니다.

struct _baz {
  short a;
  int b;
  float c;
};

typedef struct _baz baz;  // Declare baz as an alias for _baz.

baz myBaz;               // Is the same as: struct _baz myBaz;

언급URL : https://stackoverflow.com/questions/4698600/whats-the-syntactically-proper-way-to-declare-a-c-struct

반응형