有没有办法在不使用void指针的情况下返回C函数中的任何类型?

时间:2019-10-18 20:33:47

标签: c

我对C语言开发还很陌生,我想知道是否有任何方法可以像下面的Java代码那样在C函数中返回任何类型:

public static Object returnAnyType(Object anyType){
    //example useless code
    return anyType;
}
public static void main(String[] args) {
    System.out.println(returnAnyType('c'));
    // outs 'c'
}

我知道有一种方法可以返回任何类型的指针作为C中的void指针:

void* returnAny(void* anyType){
    //example useless code
    return anyType;
}

void main(){
    char ch = 'c';
    printf("%c\n", *(char*)returnAny(&ch));
    // outs 'c'
}

,我想知道是否有可能在C语言中使用相同的上述Java代码,而不必在返回类型和参数中使用void指针。 到目前为止,我已经尝试将void用于返回类型,但是我的编译器不接受没有返回类型的return语句。

2 个答案:

答案 0 :(得分:5)

在C语言中很难表达对象之间的关系。一个对象只是一个特定的内存布局,因此无法在它们之间进行强制转换。您可以定义转换函数,但仅此而已。

由于没有对象之间的关系概念,因此也没有诸如Java的Object之类的对象。

因此,不仅不可能有一个可以返回更通用值的函数,而且不可能定义一个可以返回多种类型的函数。

void*仅由于任何指针都可以转换为void*而起作用,在任何意义上都不是特殊的。

答案 1 :(得分:5)

是的。 有一种方法可以在C函数中不使用空指针就返回[一种类型的选择] 。定义为包含两个成员的结构

  • 定义了所有感兴趣类型的并集。
  • 一个枚举,其值指示正在传递的类型。

由于C不是JavaPython之类的面向对象语言,因此用于完成C中您想要的方法的方法并不像其他方法那样优雅语言,但是我已经在C语言中使用了此方法,并完成了工作:

typedef enum {
   CHAR,
   INT,
   DOUBLE,
   UCHAR,
   UINT,
   ...  //etc etc etc
} TYPE;

typedef union  {
   char char_var;
   int  int_var;
   double dble_var;
   unsigned char uchar_var;
   unsigned int uint_var;
   ... /// etc etc
}VAR;

typedef struct {
   VAR var;  // one of the types contained in union
   TYPE type;  // corresponding emum value indicating type sent
} DATA;

DATA data *pData;

此原型可用于传递任何类型(在上面的结构和联合中定义):

DATA * returnAnyType(DATA *data);

一旦函数处理了输入并返回,返回的值就可以通过printf语句输入到switch语句中。一个非常裸露的例子说明了:

int main(void)
{
    DATA dataout = {12, INT};

    DATA *datain = returnAnyType(&dataout);
    if(datain)
    {
        switch( datain->type)  {
            case (CHAR):
                printf("Type returned is \"char\", its value is: %c", datain->var.char_var);
                break;
            case (INT):
                printf("Type returned is \"int\", its value is: %d", datain->var.int_var);
                break;
            // and so on
        }
        free(datain); memory created in called function, free here.
    }

    return 0;
}

DATA * returnAnyType(const DATA *data)
{
    /////////////////////////////////////////////////////////////////////// 
    // Do what ever manipulation is needed with "data" in this section, 
    // then package into pD for the return trip
    /////////////////////////////////////////////////////////////////////

    DATA *pD = calloc(1, sizeof *pD);//create pointer instance for return
                                     //!! must be free in caller !!
    if(pD)
    {
        pD->type = data->type;
        switch (pD->type) {
            case CHAR:
                pD->var.char_var = data->var.char_var;
                break;
            case INT:
                pD->var.int_var = data->var.int_var;
                break;
            // and so on ...
        }
    }

    return pD;//free in caller function
}