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

R.L*_*.LM 1 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'
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Pau*_*l92 5

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

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

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

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


ryy*_*ker 5

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

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

因为C不是诸如Java或的面向对象语言Python,所以用于完成所需内容的方法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;
Run Code Online (Sandbox Code Playgroud)

该原型可用于传递任何类型(在上面的struct和union中定义):

DATA * returnAnyType(DATA *data);
Run Code Online (Sandbox Code Playgroud)

函数处理完输入并返回后,可以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
}
Run Code Online (Sandbox Code Playgroud)