2010-11-19 9 views
27

구조체에 함수가 포함되어 있습니까?구조체의 함수

+0

일반적인 C 프로그래밍에는 고유 한 이점이 있습니다. C에서는 모든 함수가 전역 공간에 있으므로 함수에 숨겨서 정보를 숨기지 않습니다. paxdiablo의 예제는 함수를 구조체로 구성하는 방법이지만 사용하려면 각 함수를 역 참조해야합니다. C의 표준 조직 구조는 File이며, 헤더의 인터페이스와 소스의 구현입니다. 이것이 libc가 수행되는 방식이며 거의 모든 C 라이브러리가 수행되는 방식입니다. –

답변

33

아니요, 그러나 그들은 함수 포인터를 포함 할 수 있습니다. 당신의 목적은 C에서 다형성의 형태를 할 경우

은 다음 네, 수행 할 수 있습니다

typedef
typedef struct { 
    int (*open)(void *self, char *fspec); 
    int (*close)(void *self); 
    int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz); 
    int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz); 
    // And data goes here. 
} tCommClass; 

위에서 내가 범용 통신 라이브러리 생성 된 구조였다. 변수를 초기화하기 위해, 당신은 것입니다 :

다음
tCommClass *makeCommTcp (void) { 
    tCommClass *comm = malloc (sizeof (tCommClass)); 
    if (comm != NULL) { 
     comm->open = &tcpOpen; 
     comm->close = &tcpOpen; 
     comm->read = &tcpOpen; 
     comm->write = &tcpWrite; 
    } 
    return comm; 
} 

tCommClass *makeCommSna (void) { 
    tCommClass *comm = malloc (sizeof (tCommClass)); 
    if (comm != NULL) { 
     comm->open = &snaOpen; 
     comm->close = &snaOpen; 
     comm->read = &snaOpen; 
     comm->write = &snaWrite; 
    } 
    return comm; 
} 

tCommClass *commTcp = makeCommTcp(); 
tCommClass *commSna = makeCommSna(); 

, 함수를 호출하기 위해, 무언가 같이이 방법으로

// Pass commTcp as first params so we have a self/this variable 
// for accessing other functions and data area of object. 
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000"); 

, 하나의 유형은 TCP, SNA, RS232에 사용될 수 또는 심지어 캐리어 pidgeons, 정확히 같은 인터페이스.

+1

이것은 struct/classes와의 차이점 중 하나이기도합니다. 왜냐하면 난 차이점은 구조체가 기본 public을 가지고 있고 클래스가 기본 private 인 것입니다. – JoshMachine

+0

@Josh, 저는 여러분이 public/private에 대해 C++의 struct/union 사이의 유일한 차이점이라고 생각합니다. 이 질문은 C.에 관한 것이 었습니다. C++에서 함수가 _are_ 용의자로 의심됩니다.'struct xyz {int fn (void); } a;는 g ++에서 잘 작동했습니다. – paxdiablo

+0

아, 나는 C 태그를 보지 못했다. 의심을 해결하는 +1! – JoshMachine

5

편집 '데이터 유형'

C.에 struct 유형 만 포함 할 수 있습니다되지 않은 데이터의 사용과 모호성을 정리.

ISO C99 표준의 섹션 6.7.2.1부터.

구조 또는 조합은 불완전하거나 함수 타입 (따라서 구조 자체의 인스턴스를 포함하지 아니하고 인스턴스 자체 에 대한 포인터를 포함 할 수있다)을 제외한 갖는 부재를 포함하지 않는다 둘 이상의 명명 된 구성원이있는 구조의 마지막 멤버 에 불완전한 배열 유형이있을 수 있습니다. 그러한 구조 (그리고 어쩌면 같은 구조체를 포함하는 임의의 합집합)는 배열의 구조체 또는 요소가되어서는 안됩니다.

+0

표준을 가리키는 +1 – Jay

+0

"데이터 유형 포함"은 위험 할 정도로 모호합니다 (유형을 선언 할 수있는 C++ 사용자 이상) - "데이터 포함"이 더 정확 해 보입니다. 모든 표준은 분명하지만 ...-). –

0

C에서는 구조체가 함수 포인터가 아닌 데이터 값을 포함 할 수 있습니다. C에서는 허용되지 않지만 gcc를 사용하면 다음과 같이 작동합니다. 그래서 혼란 스러워요

enter code here 

#include <stdio.h> 

struct st_func_ptr{ 
     int data; 
     int (*callback)(); 
}; 

int cb(){ 
     printf(" Inside the call back \n"); 
     return 0; 
} 

int main() { 
     struct st_func_ptr sfp = {10, cb}; 

     printf("return value = %d \n",sfp.callback()); 

     printf(" Inside main\n"); 
     return 0; 
} 

...

+1

누가 구조체에'C '의 함수 포인터를 가질 수 없다고 하던데요? – detly

+2

네, 혼란스러워하고있는 것 같습니다. 함수 포인터는 허용되며 함수 자체는 허용되지 않습니다. –

+0

콜백은 int를 반환하는 0 매개 변수가있는 함수에 대한 포인터입니다. C는 함수 시그니처 인 과 일치하는 함수를 참조하여 콜백에 할당 할 수 있습니다. 초기화리스트의 사용은 새롭고 특별한 것입니다. printf 문은 유효하지만 좋지 않은 스타일입니다. 의도에 대해 혼란스러워하며 구조체 정의에서 멀리 떨어진 곳에서 본 것이 있다면 그게 무엇인지에 대해 당황스러워서 사냥을해야 할 수도 있습니다. –

0

그것은 모든 권리입니다. 리눅스 커널 코드에는 많은 구조체에 함수가 포함되어 있습니다. 같은 :

/* 


* The type of device, "struct device" is embedded in. A class 
* or bus can contain devices of different types 
* like "partitions" and "disks", "mouse" and "event". 
* This identifies the device type and carries type-specific 
* information, equivalent to the kobj_type of a kobject. 
* If "name" is specified, the uevent will contain it in 
* the DEVTYPE variable. 
*/ 
struct device_type { 
     const char *name; 
     struct attribute_group **groups; 
     int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 
     void (*release)(struct device *dev); 
     int (*suspend)(struct device * dev, pm_message_t state); 
     int (*resume)(struct device * dev); 
}; 
+0

글쎄, 그것들은 함수에 대한 포인터입니다 - 초기화하는 데 약간의 노력을해야한다는 점을 제외하고는 거의 동일합니다. NULL이나 유효하지 않은 값을 사용할 때 실행하려고 할 위험이 있으며 런타임에 변경할 수 있습니다. .. –

0

예는 가능한 함수를 선언하고 함수 정의가 허용되지 않고, 그 함수 포인터를해야합니다.

C99 태그 구조를 기반으로합니다.

록쉬 V

0
그들이 할 수있는

하지만 보통의 C 프로그래밍에는 고유 한 장점이 없습니다.

C에서는 모든 함수가 전역 공간에 있으므로 함수에 숨겨서 정보를 숨길 수 없습니다.paxdiablo의 예제는 함수를 구조체로 구성하는 방법이지만 사용하려면 각 함수를 역 참조해야합니다.

C의 표준 조직 구조는 File이며, 헤더의 인터페이스와 소스의 구현입니다.

이것이 libc가 수행되는 방식이며 거의 모든 C 라이브러리가 수행되는 방식입니다.

Moder C 컴파일러를 사용하면 동일한 소스 파일에서 함수를 정의하고 구현할 수 있으며 헤더 파일에 정적 함수를 구현할 수도 있습니다. 이것은 불행하게도 어디로 가는지에 대한 혼란을 가져오고, 함수를 구조체로 밀어 넣는 것과 같은 특별한 솔루션, 헤더가없는 소스 전용 프로그램 등을 얻을 수 있습니다. 그런 식으로 구현을 인터페이스에서 분리하는 이점을 잃게됩니다.

0

아니요. 구조체에는 함수 선언을 포함 할 수 없지만 함수 정의를 포함 할 수 있습니다. 구조체에는 데이터 형식, 포인터, 다른 함수에 대한 포인터 만 포함될 수 있습니다. 함수에 대한 포인터를 만들 수 있고 구조에서 액세스 할 수 있습니다.

#include<iostream> 
#include<cstring> 
using namespace std; 

struct full_name 
{ 
    char *fname; 
    char *lname; 
    void (*show)(char *,char*); 
}; 

void show(char *a1,char * a2) 
{ 
    cout<<a1<<"-"<<a2<<endl; 
} 

int main() 
{ 

struct full_name loki; 
loki.fname="Mohit"; 
loki.lname="Dabas"; 
loki.show=show; 
loki.show(loki.fname,loki.lname); 


return 0; 

} 
관련 문제