我知道这在 C 语言中void type意味着根本没有价值 C语言中看到过一些代码,其中一些参数变量被作为 void 指针传递:

return_type my_function_signature(void* param1, int num_count, double real_value){
      type_to_cast_to var_param1 = (type_to_cast_to *)param1;
      // write something here
    enter code here
    return return_value;

}

void* param1我想知道,当在函数主体中确切知道要转换的类型时,在参数列表中有什么用?

它不像 C++ 中的模板函数

有 C 和 C++ 专家能提供什么帮助吗?

18

  • 8
    真正将你的问题限制在“C”或“C++”上。在 C++ 中,仅void*在处理遗留的“C”API 或知道模板和类型擦除的含义时使用。


    – 


  • 1
    @Eljay 在 C++ 中这样做的风险是,人们可能会尝试将原始数据转换为尚未开始其生命周期的类实例,因此这是不正确的。


    – 

  • 3
    malloc个例子,它返回一个指向没有任何特定类型的对象的指针,直到它被用来存储某些东西。


    – 

  • 3
    一定要在 C 环境中提问。如果你在 C++ 环境中提问,你只会得到一大堆“为什么要自取灭亡?”的评论。如果你很幸运,有人会写出一个答案,说明如何void在每个不涉及遗留代码的实例中避免使用指针。这回答了这个问题“在 C++ 中通常没用”。


    – 


  • 7
    可能会引起一些混淆,因为该void类型代表“无”,但实际上是指向“任何事物”void*的指针


    – 


最佳答案
2

使用作为参数对于回调函数void *很有用,其中参数的确切类型不一定为接受回调的函数所知,但实例化它的程序员知道。

当处理通用数据且具体类型未知时它也很有用。

一个众所周知的例子是qsort标准库中的函数,它具有以下声明:

   void qsort(void *base, size_t nmemb, size_t size,
              int (*compar)(const void *, const void *));

这里,base参数指向数组的开头,而函数指针则compar指向两个要比较的对象。在这两种情况下,qsort函数都不知道数组/元素的类型是什么。

假设您要对 数组int和 数组进行排序float。您需要创建以下回调函数:

int comp_int(const void *p1, const void *p2)
{
    const int *i1 = p1;
    const int *i2 = p2;

    if (*i1 < *i2) {
        return -1;
    } else if (*i1 > *i2) {
        return 1;
    } else {
        return 0;
    }
}

int comp_float(const void *p1, const void *p2)
{
    const float *f1 = p1;
    const float *f2 = p2;

    if (*f1 < *f2) {
        return -1;
    } else if (*f1 > *f2) {
        return 1;
    } else {
        return 0;
    }
}

这个qsort函数的调用方式如下:

int a1[5] = { ... };
float a2[10] = { ... };
qsort(a1, 5, sizeof *a1, comp_int);
qsort(a2, 10, sizeof *a2, comp_float);

void* param1我想知道,当在函数主体中确切知道要转换的类型时,在参数列表中有什么用?

这样做几乎没有用处。如果函数需要特定的指针类型,那么我认为将参数声明为该特定类型而不是 type 不是更好的选择void *

void *相反,当函数知道指针指向的特定类型,并且不依赖于该类型时,才会使用类型的参数或返回值。在 C++ 中,许多此类情况可以通过模板化类型或使用多态类型来更好地处理,但这些替代方案在 C 中不可用。