2013-10-29 3 views
2
#include<stdio.h> 
void fun(void *x) 
{ 
    //what is the data type of 'x', since I could have passed float instead of 
    // int so first I have to check datatype of this and then proceed further. 
} 
int main() 
{ 
    int n=10; 
    fun(&n); 
} 

우리는 fun() 함수에서 'x'유형을 모른다는 것을 알 수 있습니다. 그래서 함수 인수에서 다른 정보를 사용하지 않고 어떻게 찾을 수 있습니까?C에서 알 수없는 유형의 변수의 데이터 유형을 아는 방법?

+8

당신은 할 수 없습니다, 나는 두려워. 순수한 C가 아닙니다. 추가 정보를 전달해야합니다. – Baldrick

+0

C는 인수 유형에 포함 된 것 이상을 알고 있습니다.이 경우에는 '뭔가에 대한 포인터'입니다. 도움이되는 C++에는 몇 가지 메커니즘이 있지만 단순한 'int'를 전달할 때는 작동하지 않습니다. – Rob

+0

void 포인터가 아니라 printf도 마찬가지입니다. 형식 문자열 형식으로 형식 정보를 함수에 보내어받는 데이터 형식을 알 수 있습니다. –

답변

4

C11이 type-generic expressions을 가지고는이 문제를 해결하는 데 도움이 있습니다. , 당신은 별도의 대상 기능을 구현해야합니다

float n = 10.0f; 
myFunction(&n); 

:

#define myFunction(X) _Generic((X), \ 
    int *: myFunctionInt,   \ 
    float *: myFunctionFloat,  \ 
    default: myFunctionInt   \ 
    )(X) 

void myFunctionInt(int *x); 
void myFunctionFloat(float *x); 

을 그리고 당신이 길을 호출 :이 예처럼 뭔가를 할 수

int n = 10; 
myFunction(&n); 

또는 그러나 당신은 포인터 마술을 할 수 있고 일반적인 핸들러로 전달할 수 있습니다.

+1

TIL C11에는 generics가 있습니다. –

2

C에는 런타임 유형 정보가 없습니다. 포인터를 전달하면 메모리 주소 인 알몸 포인터를 전달합니다.

void에 대한 포인터를 사용하고 있지만 형식을 알아야하는 경우 몇 가지 추가 정보를 전달해야합니다. 그렇지 않으면 fooint이고 dfoodouble이 될 것으로 예상하는 등 다양한 유형에 대해 다른 함수를 만듭니다.

2

void *로 전송할 때 유형을 알 수 없습니다. void 포인터를 사용하는 동안주의해야합니다. 왜냐하면 어떤 유형 으로든 캐스팅 할 수 있기 때문입니다. 이것이 void 포인터를 갖는 목적입니다.

2

C은 전달되는 변수 유형을 void*으로 가져올 수 없습니다. 당신이 할 수있는 유일한 것은 당신 자신에 의해 객체 지향 코드를 작성하는 것입니다. 이 같은

아마 뭔가 :

typedef struct generic_type_s 
{ 
    void* data; 
    void (*f)(void* data); 
} generic_type_t; 

void f_int(void* _data) 
{ 
    int* data = (int*)_data; 
    // Do something 
} 

int main() 
{ 
    int data1 = 10; 
    // Generic variable initialization 
    generic_type_t gv; 
    gv.data = &data1; 
    gv.f = f_int; 

    // Calling an appropriate function 
    gv.f(gv.data); 

    return 0; 
} 
0

태그가 노동 조합 사용이 일의 C 방법 :

typedef enum { 
    // will default to TypeUnitialized if unspecified in structure initializer 
    TypeUninitialized = 0, 
    TypeFloat = 1, 
    TypeInt 
} type_t; 

typedef struct { 
    type_t type; 
    union { 
     int u_int; 
     float u_float; 
    }; 
} gen_val_t; 

void fun(gen_val_t v) 
{ 
    switch (v.type) { 
    case TypeFloat: 
     // process float 
     break; 
    case TypeInt: 
     // process int 
     break; 
    default: 
     // error 
     break; 
    } 
} 

int main(int argc, char **argv) 
{ 
    gen_val_t ov = { .type = TypeFloat, 
        .u_float = 3.45 }; 
    fun(ov); 
} 
+0

궁극적으로 추가 정보가 전달됩니다. –

+0

이와 같은 수동 계측을 제외하고는 런타임에이 정보를 _getting_ 할 수있는 방법이 없습니다. 그래서 그것은 특별한 방법이 아닙니다. –

관련 문제