왜 구조체를 C로 자주 입력해야 하죠?
나는 아래와 같은 구조로 구성된 프로그램을 많이 보았다.
typedef struct
{
int i;
char k;
} elem;
elem user;
왜 이렇게 자주 필요하죠?구체적인 이유 또는 적용 가능한 영역이 있습니까?
Greg 더 이상 Greg Hewgill, typedef를 쓸 합니다.struct안가는 곳이 없어요.키 스트로크를 절약할 수 있을 뿐만 아니라 보다 추상적인 코드로 코드를 깔끔하게 만들 수 있습니다.
예를 들면
typedef struct {
int x, y;
} Point;
Point point_new(int x, int y)
{
Point a;
a.x = x;
a.y = y;
return a;
}
라는 키워드를 볼 때 더 깨끗해지기 '구조'라는 키워드를 다 볼 필요가 없을 때 더 깨끗해지기 때문에 마치 '포인트'라는 단어가 있는 언어에는 '포인트'라는 단어가 있는 것 같아요. 다음에 ㅇㅇㅇㅇ가 typedef그런 것 같아요.
이 제 에서는 '(이렇게 )', '(이렇게 하면)', '이름은 생략되어 있는데, '라는 점에 해 주세요.struct실제로 이름을 붙이는 것은 불투명 유형을 제공하려는 경우에도 유용합니다.더음음 음 음 음 、 음 음 음 、 음 음 음 、예를 들어 다음과 같습니다.
typedef struct Point Point;
Point * point_new(int x, int y);
후, 「 」를 입력합니다.struct'이것'은 다음과 같습니다.
struct Point
{
int x, y;
};
Point * point_new(int x, int y)
{
Point *p;
if((p = malloc(sizeof *p)) != NULL)
{
p->x = x;
p->y = y;
}
return p;
}
이 경우 헤더 파일의 사용자로부터 Point by 값이 숨겨져 있기 때문에 Point by 값을 반환할 수 없습니다.예를 들어 GTK+에서 널리 사용되는 기술입니다.
UPDATE: 이 사용법에 의해 매우 존중받는 C프로젝트도 있습니다.typedefstructLinux 커널은 아마도 가장 잘 알려진 프로젝트일 것입니다.Linux 커널 코딩 스타일 문서의 5장을 참조하여 Linus의 격앙된 단어를 확인하십시오.제 요점은 질문의 '해야 한다'는 것은 결국 정해진 것이 아니라는 것입니다.
얼마나 많은 사람들이 이것을 틀리는지 놀랍다.C에 typedef 구조를 입력하지 마십시오.대형 C 프로그램에서 이미 많이 오염된 글로벌 이름 공간을 불필요하게 오염시킵니다.
또한 태그명이 없는 typedef'd 구조체는 헤더 파일 간의 정렬 관계를 불필요하게 만드는 주요 원인이다.
고려사항:
#ifndef FOO_H
#define FOO_H 1
#define FOO_DEF (0xDEADBABE)
struct bar; /* forward declaration, defined in bar.h*/
struct foo {
struct bar *bar;
};
#endif
.시켜 typedefs에서 할 수 .h의 컴필수단위FOO_DEF「bar」의 .foo파일 "이것"은 "이것.h" 파 h h 。
또, 태그명과 멤버명은 네임스페이스가 다르기 때문에, 다음과 같은 읽기 쉬운 코드를 쓸 수 있습니다.
struct foo *foo;
printf("foo->bar = %p", foo->bar);
네임스페이스는 분리되어 있기 때문에 구조 태그 이름과 일치하는 변수 이름 지정 시 충돌하지 않습니다.
당신의 코드를 유지해야 한다면 당신의 typedef'd 구조를 제거하겠습니다.
Dan Saks의 오래된 기사(http://www.ddj.com/cpp/184403396?pgno=3):
구조물에 이름을 붙이는 C언어의 규칙은 좀 이상하지만, 꽤 무해합니다.하지만, C++의 클래스로 확장되면, 이러한 규칙들은 벌레들이 기어 다닐 수 있는 작은 틈을 열어준다.
C에서는 이름이 에 표시됩니다.
struct s { ... };태그입니다.태그 이름이 형식 이름이 아닙니다.위의 정의에 따라 다음과 같은 선언이 있습니다.
s x; /* error in C */ s *p; /* error in C */C의 에러입니다.다음과 같이 써야 합니다.
struct s x; /* OK */ struct s *p; /* OK */결합 및 열거 이름도 유형이 아닌 태그입니다.
C에서 태그는 다른 모든 이름(함수, 유형, 변수 및 열거 상수)과 구별됩니다.C 컴파일러는 다른 모든 이름을 포함하는 테이블과 물리적으로 분리되어 있지 않은 경우 개념적으로 심볼 테이블에 태그를 유지합니다.따라서, C프로그램은 태그와 같은 범위의 같은 철자를 가진 다른 이름을 가질 수 있습니다.예를들면,
struct s s;는 유형 구조의 변수s를 선언하는 유효한 선언입니다.좋은 방법은 아니지만 C 컴파일러는 이를 수용해야 합니다.나는 C가 왜 이렇게 설계되었는지에 대한 근거를 본 적이 없다.항상 실수라고 생각했지만, 결국 실수였다.
많은 프로그래머(진짜 포함)는 구조 이름을 유형 이름으로 생각하는 것을 선호하기 때문에 typedef를 사용하여 태그의 별칭을 정의합니다.예를 들어, 정의
struct s { ... }; typedef struct s S;에서와 같이 구조 s 대신 S를 사용할 수 있습니다.
S x; S *p;프로그램은 형식과 변수(또는 함수 또는 열거 상수)의 이름으로 S를 사용할 수 없습니다.
S S; // error좋아요.
구조, 결합 또는 열거 정의의 태그 이름은 옵션입니다.많은 프로그래머가 구조 정의를 typedef로 접고 다음과 같이 태그를 모두 제거합니다.
typedef struct { ... } S;
에서는 C++가 하지 않은 합니다.typedef은 미묘한 이름 숨기기 문제를 일으킬 수 있습니다.하려면 을 하는 typedefC++의 클래스나 구조도, 언뜻 보면 불필요해 보일지 모르지만.에서는 C++를 typedef숨겨진 이름의 은닉은 잠재적인 문제의 원인이 아니라 컴파일러가 알려주는 오류가 됩니다.
「」의 typedef를 쓰지 않아도 된다struct해당 유형의 변수를 선언할 때마다 다음을 수행합니다.
struct elem
{
int i;
char k;
};
elem user; // compile error!
struct elem user; // this is correct
이 문제로 인해 항상 enums 및 structures를 입력해야 하는 또 하나의 좋은 이유가 있습니다.
enum EnumDef
{
FIRST_ITEM,
SECOND_ITEM
};
struct StructDef
{
enum EnuumDef MyEnum;
unsigned int MyVar;
} MyStruct;
구조(EnuumDef)의 EnumDef에 오타가 있음을 알 수 있습니까?이는 오류(또는 경고) 없이 컴파일되며 (C 표준의 문자 그대로 해석에 따라) 정확하다.문제는 구조 내에 새로운 (빈) 열거 정의를 작성했다는 것입니다.이전 정의 EnumDef를 사용하지 않습니다.
typedef와 같은 종류의 오타가 있으면 알 수 없는 유형을 사용하는 경우 컴파일러 오류가 발생할 수 있습니다.
typedef
{
FIRST_ITEM,
SECOND_ITEM
} EnumDef;
typedef struct
{
EnuumDef MyEnum; /* compiler error (unknown type) */
unsigned int MyVar;
} StructDef;
StrructDef MyStruct; /* compiler error (unknown type) */
나는 항상 정형화된 구조와 열거를 옹호할 것이다.
타이핑(말장난 의도 없음)을 저장할 뿐만 아니라 더 안전하기 때문입니다.
찬반 양론이 있는 것으로 나타났습니다.유용한 정보 출처는 "Expert C Programming"(제3장)이다.간단히 말해 C에는 태그, 유형, 구성원 이름 및 식별자 등 여러 네임스페이스가 있습니다. typedef는 타입의 에일리어스를 도입하여 태그 이름 공간에 배치합니다. ,,
typedef struct Tag{
...members...
}Type;
는 두 가지를 정의합니다.태그 네임스페이스에 태그 하나와 유형 네임스페이스에 유형 하나. 둘 다 할 수요.Type myType ★★★★★★★★★★★★★★★★★」struct Tag myTagType은 하다, 하다, 하다, 하다.struct Type myType ★★★★★★★★★★★★★★★★★」Tag myTagType을 하면과 같은 내용이 다음과 같습니다.또한 다음과 같은 선언에서 다음과 같이 처리한다.
typedef Type *Type_ptr;
유형에 대한 포인터를 정의합니다.따라서 다음과 같이 선언합니다.
Type_ptr var1, var2;
struct Tag *myTagType1, myTagType2;
var1 ,var2 ★★★★★★★★★★★★★★★★★」myTagType1 포인터입니다만,myTagType2
위에서 언급한 책에서, 그것은 타이핑 구조가 프로그래머가 구조라는 단어를 쓰는 것을 막을 뿐이기 때문에 그다지 유용하지 않다고 언급하고 있다.하지만 다른 많은 C 프로그래머들처럼 저도 반대합니다.C에 다형성을 실장하고 싶을 때는, 일부의 이름을 난독화하는 경우가 있습니다만(그래서 커널과 같은 큰 코드 베이스에서는 추천하지 않습니다).자세한 것은 이쪽을 참조해 주세요.예:
typedef struct MyWriter_t{
MyPipe super;
MyQueue relative;
uint32_t flags;
...
}MyWriter;
다음 작업을 수행할 수 있습니다.
void my_writer_func(MyPipe *s)
{
MyWriter *self = (MyWriter *) s;
uint32_t myFlags = self->flags;
...
}
외부 멤버 멤버)에 접속할 수 있습니다.flags 구조 )에 의한MyPipe를해 주세요.)을 사용하다이 하다보다 덜 .(struct MyWriter_ *) s;이러한 기능을 수행하고자 할 때마다 항상 사용할 수 있습니다.이러한 경우 코드에 기술을 많이 사용하는 경우 특히 간단한 참조가 중요합니다.
를 붙입니다.typedefmacros.ed type과 입니다. 다음과 같은 경우:
#define X char[10] or
typedef char Y[10]
그런 다음 선언할 수 있습니다.
unsigned X x; but not
unsigned Y y;
스토리지 지정자)에는되지 않기 에 대해서는 쓰지 .volatile ★★★★★★★★★★★★★★★★★」const를 참조해 주세요.
기본부터 시작해서 더 열심히 합시다.
다음은 구조 정의의 예입니다.
struct point
{
int x, y;
};
은 기기이 here here here here here here here here here here here here.point는 옵션입니다.
구조물은 정의 중 또는 정의 후에 선언할 수 있습니다.
정의 중 선언
struct point
{
int x, y;
} first_point, second_point;
정의 후 선언
struct point
{
int x, y;
};
struct point first_point, second_point;
위의 깊게 .struct point코드의 나중에 해당 유형을 작성하기로 결정한 경우 해당 유형의 구조를 선언합니다.
「」라고 입력합니다.typedef Blueprint를하여 나중에 타입, "Playture"를 typedef그 정의 중에, 타이핑의 진행 상황을 보존할 수 있기 때문에, 좋은 생각이 될 수 있습니다.
typedef struct point
{
int x, y;
} Points;
Points first_point, second_point;
사용자 지정 유형 이름 지정 시 주의사항
사용자 지정 유형 이름 끝에 _t 접미사를 사용할 수 없도록 하는 것은 없지만 POSIX 표준에서는 표준 라이브러리 유형 이름을 나타내기 위해 접미사 _t를 사용합니다.
Linux 커널 코딩 스타일 5장은 사용의 장점과 단점을 제시합니다.typedef.
"vps_t" 같은 것은 사용하지 말아 주세요.
구조 및 포인터에 typedef를 사용하는 것은 실수입니다.이 표시되었을 때
vps_t a;그게 무슨 뜻일까요?
반대로, 만약 이렇게 적혀있다면
struct virtual_container *a;'a'가 뭔지 알 수 있어요
많은 사람들이 typedefs가 가독성에 도움이 된다고 생각한다.그렇지 않아요.이러한 기능은 다음 경우에만 유용합니다.
(a) 완전히 불투명한 물체(typedef가 대상물을 숨기기 위해 적극적으로 사용되는 경우).
예: "pte_t" 등 적절한 접근자 기능을 통해서만 접근할 수 있는 불투명한 객체.
메모! 불투명도나 '액세서 기능' 자체는 좋지 않습니다.pte_t 등에는, 휴대할 수 있는 정보가 전혀 없기 때문입니다.
(b) "int"인지 "long"인지에 관계없이 추상화가 혼동을 피하는 데 도움이 되는 명확한 정수형.
u8/u16/u32는 여기보다 카테고리(d)에 더 적합하지만 완전히 미세한 타이프입니다.
참고! 다시 말하지만 여기에는 이유가 있어야 합니다.만약 어떤 것이 "서명되지 않은 긴" 것이라면, 그렇게 할 이유가 없습니다.
typedef unsigned long myflags_t;단, 특정 상황에서는 "지정된 int"가 될 수 있고 다른 구성에서는 "지정된 int"가 될 수 있는 명확한 이유가 있는 경우에는 반드시 typedef를 사용하십시오.
(c) sparse를 사용하여 문자 그대로 새로운 타입을 작성하여 타입 체크를 하는 경우.
(d) 특정 예외적인 상황에서 표준 C99형과 동일한 새로운 형식
비록 눈과 뇌가 'uint32_t'와 같은 표준 타입에 익숙해지는 데는 짧은 시간이 걸릴 것이지만, 어떤 사람들은 어쨌든 그것의 사용에 반대한다.
따라서 Linux 고유의 'u8/u16/u32/u64' 유형 및 표준 유형과 동일한 서명된 해당 유형은 허용됩니다. 단, 사용자 자신의 새 코드에서는 필수 사항이 아닙니다.
하나 또는 다른 유형 집합을 이미 사용하는 기존 코드를 편집할 때는 해당 코드의 기존 선택 사항에 따라야 합니다.
(e) 사용자 공간에서 사용하기에 안전한 형식입니다.
사용자 공간에 표시되는 특정 구조에서는 C99 타입을 필요로 하지 않으며 위의 'u32' 폼을 사용할 수 없습니다.따라서 사용자 공간과 공유되는 모든 구조에서 __u32 및 유사한 유형을 사용합니다.
다른 경우도 있을 수 있지만 기본적으로 이러한 규칙 중 하나를 명확하게 일치시킬 수 없는 한 절대 typedef를 사용하지 않는 것이 원칙입니다.
일반적으로 포인터 또는 직접 액세스할 수 있는 요소가 있는 구조는 typedef가 되어서는 안 됩니다.
나는 typedef로 전향 선언이 가능하다고 생각하지 않는다.structure, enum 및 union을 사용하면 종속성(알고 있는)이 양방향일 때 전달 선언이 허용됩니다.
스타일: C++에서 typedef를 사용하는 것은 매우 타당합니다.이는 여러 개의 파라미터 또는 변수 파라미터가 필요한 템플릿을 다룰 때 필요할 수 있습니다.typedef를 사용하면 이름을 올바르게 지정할 수 있습니다.
C 프로그래밍 언어에서는 그렇지 않습니다.typedef의 사용은 대부분의 경우 데이터 구조 사용을 난독화하는 데 도움이 되지 않습니다.데이터 유형을 선언하는 데 사용되는 키 입력은 { structure (6), enum (4), union (5) }개뿐이므로 구조의 별칭 지정은 거의 사용되지 않습니다.그 데이터 유형은 유니온입니까, 아니면 구조물입니까?알기 쉬운 비표준 선언을 사용하면 어떤 유형인지 바로 알 수 있습니다.
Linux는 이 에일리어싱 넌센스 typedef가 가져오는 것을 철저히 피한 채 기술되어 있습니다.그 결과 미니멀하고 깔끔한 스타일이 탄생했다.
A > typedef는 데이터 타입에 대해 보다 의미 있는 동의어를 작성할 수 있도록 함으로써 프로그램의 의미와 문서화에 도움이 됩니다.또, 휴대성의 문제(K&R, pg147, C prog lang)에 대해서 프로그램을 파라메타화할 수 있습니다.
B > 구조가 유형을 정의합니다.Structures를 통해 취급 편의성을 위해 일련의 변수(K&R, pg127, C prog lang)를 단일 단위로 쉽게 그룹화할 수 있습니다.
C > typedef는 위의 A에서 설명하고 있습니다.
D> 나에게 구조체는 커스텀타입, 컨테이너, 컬렉션, 네임스페이스 또는 복잡한 타입이지만 typedef는 더 많은 닉네임을 만드는 수단일 뿐입니다.
C 언어에서 structure/union/enum은 C 언어 프리프로세서에 의해 처리되는 매크로 명령입니다(#include 및 기타 처리를 하는 프리프로세서와 혼동하지 마십시오).
즉, 다음과 같이 됩니다.
struct a
{
int i;
};
struct b
{
struct a;
int i;
int j;
};
structure b는 다음과 같이 확장됩니다.
struct b
{
struct a
{
int i;
};
int i;
int j;
}
따라서 컴파일 시 스택 상에서 다음과 같이 진화합니다.b : int ai int i int j
또한 C 프리프로세서 라운드를 종료할 수 없는 디클라레이션루프에서 자기 참조 구조를 갖는 것이 어려운 이유입니다.
typedef는 유형 지정자이며, 이는 C 컴파일러만이 이를 처리하며 어셈블러 코드 구현을 최적화하기 위해 원하는 대로 수행할 수 있음을 의미합니다.또한 préprocessor가 구조물에 사용하는 것과 같이 type par의 구성원을 멍청하게 소비하지 않고 보다 복잡한 기준 구성 알고리즘을 사용합니다.따라서 다음과 같은 구조를 사용합니다.
typedef struct a A; //anticipated declaration for member declaration
typedef struct a //Implemented declaration
{
A* b; // member declaration
}A;
이 허용되고 완전히 기능합니다.이 실장에서는 컴파일러 타입의 변환에도 액세스 할 수 있어 실행 스레드가 초기화 함수의 어플리케이션필드에서 벗어날 때 일부 도청 효과가 배제됩니다.
이것은 C의 typedef가 외로운 구조체보다 C++ 클래스에 가깝다는 것을 의미합니다.
사용자가 구조체에 부여한 이름(선택사항)은 태그 이름이라고 불리며, 앞서 설명한 바와 같이 유형 자체는 아닙니다.유형에 액세스하려면 구조 접두사가 필요합니다.
GTK+는 차치하고라도 tagname이 구조체 타입에 대해 typedef와 같이 일반적으로 사용되는지는 잘 모르겠습니다.따라서 C++에서는 struct 키워드를 생략하고 tagname을 유형 이름으로 사용할 수 있습니다.
struct MyStruct
{
int i;
};
// The following is legal in C++:
MyStruct obj;
obj.i = 7;
typedef는 데이터 구조의 공의존 집합을 제공하지 않습니다.이것은 typedef에서는 할 수 없습니다.
struct bar;
struct foo;
struct foo {
struct bar *b;
};
struct bar {
struct foo *f;
};
물론 언제든지 추가할 수 있습니다.
typedef struct foo foo_t;
typedef struct bar bar_t;
그게 정확히 무슨 의미가 있는 거죠?
C99의 typedef가 필요한 것으로 나타났습니다.구식이지만 많은 툴(일명 HackRank)이 순수 C 구현으로 c99를 사용하고 있습니다.거기에 typedef가 필요합니다.
요건이 변경되었다면 (아마도 2개의 C옵션이 있다)를 변경하라는 것은 아닙니다.사이트에서 면접을 보고 있는 사람은 SOL이 될 것입니다.
'C' 프로그래밍 언어에서 키워드 'typedef'는 일부 객체(구조, 배열, 함수)의 새 이름을 선언하는 데 사용됩니다.enum type)을 클릭합니다.예를 들어 '구조-s'를 사용합니다.C에서 우리는 종종 '주' 함수의 외부에 '구조'를 선언한다.예를 들어 다음과 같습니다.
struct complex{ int real_part, img_part }COMPLEX;
main(){
struct KOMPLEKS number; // number type is now a struct type
number.real_part = 3;
number.img_part = -1;
printf("Number: %d.%d i \n",number.real_part, number.img_part);
}
구조 유형을 사용할 때마다 'struct 'something' 'name'이라는 키워드가 필요합니다.typedef는 단순히 해당 유형의 이름을 변경할 뿐이며 원하는 경우 언제든지 프로그램에서 새 이름을 사용할 수 있습니다.우리의 코드는 다음과 같습니다.
typedef struct complex{int real_part, img_part; }COMPLEX;
//now COMPLEX is the new name for this structure and if I want to use it without
// a keyword like in the first example 'struct complex number'.
main(){
COMPLEX number; // number is now the same type as in the first example
number.real_part = 1;
number.img)part = 5;
printf("%d %d \n", number.real_part, number.img_part);
}
프로그램 전체에서 사용되는 로컬 객체(구조, 배열, 가치)가 있는 경우 'typedef'를 사용하여 이름을 지정할 수 있습니다.
언급URL : https://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c
'programing' 카테고리의 다른 글
| 억양을 없애고 문자열 전체를 일반 문자로 변환할 수 있는 방법이 있나요? (0) | 2022.07.16 |
|---|---|
| 뷰티파이 대화 상자의 문자열에 새 줄을 삽입할 수 없습니다. (0) | 2022.07.16 |
| 마운트된 vue의 페이지 한 번만 다시 로드 (0) | 2022.07.16 |
| 정수가 기존의 값 집합을 가진 두 정수(포함) 사이에 있는지 여부를 확인하는 가장 빠른 방법 (0) | 2022.07.11 |
| UDP 접속의 양끝을 바인드() 및 connect()할 수 있습니까? (0) | 2022.07.11 |