2017-11-01 13 views
22

는 선언은 언급 이 책과 내가 다르게 본 것들에 따르면, 구조체에 대한 포인터를 정의 할 때, 구조체의 이름, 즉 정의되는 타입을 언급 할 필요가있다. 예를 들어,타입 구조 정의의이 포인터는 무엇을 의미합니까 (C에서)? 때문에 다른 모든 예에서</p> <pre><code>struct{ int len; char *str; } *p; </code></pre> <p>나는 구조를 이해할 수 없었다가이 포인터 p를 가리키는과 같은 포인터 정의도 유효한 경우 다음과 같이 K & R 제 6 장에서

struct example{ 
    int a; 
    ... 
}s1; 

하고,

struct example *ptr = &s1; 

때문에, PTR이 형 구조체의 예를 가리키는 그냥 구조체되지 않는다는 것을 언급한다.

또한, 특별한 관심이 있었다 :

* P-> STR가 어떤 STR 포인트를 가져옵니다; * p-> str ++ 은 (* s ++처럼) 가리키는 부분에 액세스 한 후에 str을 증가시킵니다.

p가 처음부터 따라 올 수 없으므로, 따라서 증가분과 역 참조가 없습니다.

여기에 무슨 일이 일어나고 있습니까?

미리 감사드립니다.

P. 나는 여기에서 새롭기 때문에 질문 형식에 대한 피드백도 환영 할 것입니다.

+10

첫 번째 예제에서 구조체는 * anonymous * 구조체이고'p'는 해당 익명 구조체에 대한 포인터입니다. –

+0

익명 구조 란 무엇입니까? 그것은 일종의 구조입니까, 아니면 구조체 유형이 정의되지 않았 음을 말하는 것입니까? –

+2

그것은 마치 표시된 것과 같은 이름이없는 구조입니다. 사용이 제한적이므로 자주 사용하지 않습니다. –

답변

13

struct 키워드는 기존 형식의 별칭 대신 복잡한 사용자 지정 형식 (구조라고 함)을 만드는 것을 제외하고는 typedef의 확장 버전과 비슷합니다. 선언 된 형식을 사용해야하는 것이 하나 뿐인 경우에는 형식에 대한 명시 적 이름을 제공 할 필요가 없습니다.

보고있는 첫 번째 문은 두 개의 필드가있는 구조체를 선언하지만 이름은 지정하지 않습니다. 이를 익명 구조라고합니다. 그러나 선언은 해당 유형의 포인터를 제공합니다.

이러한 선언의 가능한 경우 중 하나는 외부 라이브러리에 대한 헤더를 만드는 경우입니다. 외부 라이브러리의 헤더를 C 언어로 작성하지 않았을 수도 있습니다.이 경우 구조 유형이 불투명하거나 불완전 할 수 있습니다. 당신은 그것의 일부에 대한 편리한 참조가 필요할뿐입니다. 구조를 익명으로 만들면 쉽게 할당 할 수 없지만 포인터를 통해 상호 작용할 수 있습니다.

보다 일반적으로이 표기법은 명명 된 구조 또는 적어도 별칭이 지정된 구조와 함께 사용됩니다. 두 번째 문은이 경우

struct example { ... } s1, *ptr; 

로 다시 작성할 수 있습니다, struct example *ptr = &s1;ptr = &s1; 될 것이다.

보다 일반적인 경우는 익명 구조를 typedef과 함께 사용하면 struct 키워드를 포함하지 않는 사용자 지정 형식 이름을 만들 수 있습니다.두 번째 예는 s1의 유형이 경우 example하지 struct example 것을

typedef struct { ... } example, *pexample; 
example s1; 
pexample ptr; // alternatively example *ptr; 
ptr = &s1; 

참고로 다시 작성할 수 있습니다.

+0

"* * 해당 유형에 대한 포인터 제공 *"문구가 더 정확하게 작성되어야합니까? "* 해당 유형의 포인터 *"를 제공해야합니까? 우리가 타입 자체에 대한 포인터를 가지고 있다는 것을 당신의 대답에 오인하였습니다. – Dan

+0

@ Dan. 결정된. 붙잡아 줘서 고마워. –

2

다른 사용법 (익명 구조체)은 유니온 또는 다른 구조체 내에서 구조체를 사용하는 것입니다.이 구조체는 기본적으로 프로그래머의 관점에서 볼 때 매우 유용한 특정 부모 공용 구조체에 해당 구조체의 사용을 제한합니다 이런 코드를 보면 구조체 나 내부의 공용체의 컨텍스트에서 로컬로 사용되는 정보를 얻을 수 있습니다. 그 이상입니다. (이름 지정에서 우리를 구해줍니다.)


또한이 익명 구조를 사용하면 이미 존재하는 인스턴스 이외의 하나의 인스턴스를 할당 할 수 없습니다.

예 :-(스탁의 코멘트 : 그것을 사용하는 방법)

struct { 
    int a; 
    int b; 
} p; 

scanf("%d",&p.a); 
+0

또는 우발적으로 우리 자신 중 하나를 할당하십시오. –

+0

@MadPhysicist : 예 true.you는 익명 일 때 할당 할 수 없습니다 ... 한 번만 사용하면됩니다 ... – coderredoc

+0

anon struct 요소를 어떻게 참조 하시겠습니까? – stark

0

당신이 구조체 (또는 노동 조합의 임시, 일회용 정의를 필요한 경우) 유용하지 않을 것입니다 범위가 지정되지 않은 경우 anonymous or unnamed structs and unions을 사용합니다. 이렇게하면 구조체를 사용하기 전에 구조체를 선언 할 필요가 없으며 복잡한 유형의 경우 내부 형식 (예 : here)을 선언 할 필요가 없습니다.

3

우선 다음과 같은 간단한 프로그램을 고려 들어

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    struct { 
     int len; 
     char *str; 
    } *p; 

    p = malloc(sizeof(*p)); 

    p->str = "Hello Nihal Jain"; 
    p->len = strlen(p->str); 

    while (*p->str) putchar(*p->str++); 
    putchar('\n'); 

    free(p); 

    return 0; 
} 

그것의 출력은

struct { 
     int len; 
     char *str; 
    } *p; 

은 익명의 유형의 포인터가 선언이 선언에

Hello Nihal Jain 

그래서입니다 구조. 포인터 자체는 초기화되지 않습니다. 당신은 구조 유형의 개체도 선언이 존재하거나 프로그램에 필요하기 때문에 구조의 이름이 필요하지 않습니다이 간단한 프로그램의 예를

struct { 
     int len; 
     char *str; 
    } *p = malloc(sizeof(*p)); 

을 위해 쓸 수 있습니다.

구조체 유형의 객체를 선언 할 수 없지만이 경우에는 필요하지 않습니다. 표준 C 구조 또는 조합에 따라

은 (는) 구조체 선언리스트가 존재하는 경우 상기 식별자가 선택적임을 알

 
struct-or-union-specifier: 
    struct-or-union identifieropt { struct-declaration-list } 
    struct-or-union identifier 

같이 선언된다. 따라서 이름 지정되지 않은 구조체를 형식 지정자로 사용할 수 있습니다.

열거 형을 사용한 또 하나의 예입니다. 열거 유형을 선언하지 않고 열거자를 선언 할 수 있습니다.

enum { EXIT_SUCCESS = 0, EXIT_FAILURE = -1 }; 
예를

를 들어 당신은 프로그램의 이러한 요구 사항이없는 경우 열거 형의 객체를 선언하지 않고 유형 int을 가지고있는 열거를 사용할 수 있습니다.

+0

TIL 당신은 여전히'sizeof (* p)'를 통해 크기를 추출 할 수 있습니다. 매우 +1. –

+0

@MadPhysicist 또는'sizeof * p'. '()'는 필요하지 않습니다. (스타일 문제) – chux

+0

@chux. 요점을 알았어. 나는 어디에서나 괄호를 넣는 것을 선호합니다. –