【问题标题】:foo(void) vs foo(void *)foo(void) 与 foo(void *)
【发布时间】:2020-03-08 09:32:23
【问题描述】:

从功能和语法上讲,原型为int foo(void)int foo(void *) 的函数有区别吗?

例如,我知道int bar(int)int bar(int *) 之间的区别——其中一个在寻找一个int,另一个在寻找一个int 指针。 void 的行为方式是否相同?

【问题讨论】:

标签: c++ c function-prototypes


【解决方案1】:

来自this answer on Software Engineering, void 根据使用方式进行特殊处理。在CC++ 中,void 用于表示an absence of a data type,,而void * 用于表示pointer which points to some data/space in memory that does not have a type. void * 不能自行取消引用,必须先转换为另一种类型。这个强制转换不需要在C 中显式,但必须在C++ 中显式。 (这就是为什么我们不强制转换 malloc 的返回值,即void *。)


当与函数一起用作参数时,void 表示完全没有任何参数,并且是唯一允许的参数。尝试像变量类型一样使用 void 或包含其他参数会导致编译器错误:

int foo(void, int);     //trying to use "void" as a parameter
int bar(void baz);      //trying to use "void" as an argument's type
main.c:1:8: error: 'void' must be the first and only parameter if specified
int foo(void, int);
       ^
main.c:2:14: error: argument may not have 'void' type
int bar(void baz);
             ^

同样不可能声明类型为void的变量:

int main(void) {
  void qux;         //trying to create a variable with type void
}
main.c:5:8: error: variable has incomplete type 'void'
  void qux;

void 作为函数的返回值表示不会返回任何数据。由于无法声明void 类型的变量,因此无法捕获void 函数的返回值,即使使用 void 指针。

void foo(int i) { return; }

int main(void) {
  void *j;
  j = foo(0);

  return 0;
}
main.c:5:5: error: assigning to 'void *' from
      incompatible type 'void'
  j = foo(0);
    ^ ~~~~~~

无类型的void * 是另一种情况。 void 指针表示指向内存中某个位置的指针,但不表示该指针处的数据类型。 (这是used to achieve polymorphism in C,例如qsort() function。)但是,这些指针可能很难使用,因为很容易意外地将它们转换为错误的类型。下面的代码不会在C 中抛出任何编译器错误,但会导致未定义的行为:

#include <stdio.h>

int main(void) {
  double foo = 47.2;    //create a double
  void *bar = &foo;     //create a void pointer to that double
  char *baz = bar;      //create a char pointer from the void pointer, which
                        //is supposed to hold a double

  fprintf(stdout, "%s\n", baz);
}

然而,下面的代码是完全合法的; casting to and from a void pointer never changes the value it holds.

#include <stdio.h>

int main(void) {
  double foo = 47.2;
  void *bar = &foo;
  double *baz = bar;

  fprintf(stdout, "%f\n", *baz);
}

47.200000

作为函数参数,void * 表示您传入的指针处的数据类型是未知的,这取决于您(程序员)来正确处理该内存位置的任何内容。作为返回值,void * 表示返回的数据类型未知或无类型,必须由程序处理。

int quux(void *);   //a function that receives a pointer to data whose type is not known, and returns an int.
void *quuz(int);    //a function that receives an int, and returns a pointer to data whose type is not known.

tl;dr 函数原型中的void表示“无数据”,表示无返回值或无参数,函数原型中的void *表示“该函数指针处的数据” is given 没有已知类型”,表示参数或返回值,其指针必须转换为不同的类型,然后才能使用指针处的数据。

【讨论】:

  • void * ... must be cast to another type first, but may be done so without an explicit cast. 在 C++ 中不是这样。在 C++ 中,转换形式 void* 必须是显式的。附言显式调用强制转换是多余的,因为根据定义,强制转换是显式转换。
  • 已更新以反映 C/C++ 差异,感谢您告诉我!
【解决方案2】:

foo(void) - 没有参数的函数

foo(void *) - 带有一个void * 参数的函数

void * 是什么?它只是指向没有指定类型的数据的指针。它可以转换为任何其他指针类型

unsigned add(void *arr)
{
   unsigned *uarr = arr;
   return uarr[0] + uarr[1];
}

【讨论】:

  • 基本答案,所以它是最好的。我只想强调这在(type) vs. (type *) Couples 世界中是一个例外,因为 void 实际上不是一种类型。
【解决方案3】:

从功能和语法上讲,原型为 int foo(void) 和 int foo(void *) 的函数有区别吗?

有区别:

int foo(void) 声明了一个不接受任何参数的函数。

int foo(void *) 声明了一个接受 void* 类型的单个参数的函数。

在 C++ 中,int foo(void) 等价于 int foo()

【讨论】:

    猜你喜欢
    • 2020-06-16
    • 2012-04-04
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2012-10-17
    • 2010-09-08
    • 1970-01-01
    相关资源
    最近更新 更多