【问题标题】:Function with 0 arguments - void vs void*?具有 0 个参数的函数 - void 与 void*?
【发布时间】:2020-11-18 07:38:04
【问题描述】:

我知道你可以像这样声明一个不带任何参数的函数:

void test()
{
    cout << "Hello world!!" << endl;
}

但我也见过

void test(void)
{
    cout << "Hello world!!" << endl;
}

void test(void*)
{
    cout << "Hello world!!" << endl;
}

我的问题是:在这里使用voidvoid* 有什么区别?

【问题讨论】:

  • 我不记得看过最后一张。我希望它需要你传递一个指向任何类型的指针。
  • test()test(void) 在 C++ 中是等价的,但在 C 中不等价。除非需要 C 兼容性,否则 former form should be preferred。函数test(void*) 与其他两个不同;它采用void* 类型的未命名参数。
  • 没有。 void* 本质上是一个无类型指针,一个原始内存地址。它可以指向任何“对象”。您可以将其设置为 null 使其指向任何内容。
  • @super 与 C 和 C++ 中的许多其他内容一样,“void”一词的含义取决于上下文。就其本身而言,它表示“无”,加上一个星号表示“任何”。 (当你谈到“静态”和“运算符”时,会很有趣。)

标签: c++ syntax void function-declaration function-definition


【解决方案1】:

C++ 中没有参数的函数的唯一形式应该是

void test();

形式:

void test(void)

这就是您在 中定义没有参数的函数的方式。但在 C++ 中,only 使用这种形式与 进行交互:

extern "C"
{
void test(void);
}

这个表格:

void test(void*)

不是没有参数的函数。它有一个未命名的void* 类型的参数。它在调用时需要一个void* 指针。

在这里查看void* 指针的解释:What does void* mean and how to use it?

【讨论】:

    【解决方案2】:

    在这里使用voidvoid* 有什么区别?

    当参数类型为void时,该函数必须在没有任何参数的情况下调用。

    当参数类型为void* 时,必须使用void* 或可以转换为void* 的参数调用函数。

    void 代表“无”,但void* 不代表“无指针”。事实上,情况恰恰相反。 void* 代表指向除void 之外的任何内容的指针。这是矛盾的,但这就是语言定义这两者的方式。

    【讨论】:

    【解决方案3】:

    我的问题是:在这里使用 void 和 void* 有什么区别?

    (void) 参数列表与空参数列表相同。 void 这里的 void 在 C++ 中什么都不做,除非需要与 C 兼容,否则是不必要的 - 请参阅答案的第二部分。

    (void*) 不接受 0 个参数。它接受 1 个参数。参数类型为void*,为指针类型。


    为什么会这样?

    因为向后兼容 C。在 C 中,(void) 是声明只接受空参数列表的函数的唯一方法。 () 参数列表声明任何函数而不指定参数。参数的数量可以是任意的,包括 0。在 C 中使用 () 参数列表正在成为一个过时的功能。

    引自 C11 标准草案 N1548:

    函数声明符(包括原型)

    标识符列表仅声明函数参数的标识符。作为该函数定义的一部分的函数声明器中的空列表指定该函数没有参数。不属于该函数定义的函数声明器中的空列表指定不提供有关参数数量或类型的信息。

    未来的语言方向

    函数声明符

    使用带空括号的函数声明符(不是原型格式的参数类型声明符)已过时。

    函数定义

    使用具有单独参数标识符和声明列表(不是原型格式的参数类型和标识符声明符)的函数定义已过时。

    C 之所以采用这种方式,是因为它与未声明参数列表的 C 的旧版本(准标准)向后兼容。

    【讨论】:

    • "() 参数列表声明了一个接受任意数量参数的函数" 你能否扩展一下“()
    • @RokoC.Buljan 这是 K&R C 的遗留物,您没有在参数列表中声明函数的参数。
    • @RokoC.Buljan 我添加了语言规则来扩展它。
    【解决方案4】:

    在 C++ 中这两个函数声明

    void test();
    

    void test(void);
    

    是等价的,意味着函数不接受任何参数。

    在 C 中,第一个函数声明声明了一个带有空标识符列表的函数,第二个函数声明声明了一个带有参数类型列表的函数,该列表实际上没有参数。

    根据 C 标准(6.9.1 函数定义):

    5 如果声明符包含参数类型列表,则声明 每个参数都应包含一个标识符,除了特殊的 由一个类型的参数组成的参数列表的情况 void,在这种情况下不应有标识符。没有声明 列表如下。

    这个函数的声明(也是它的定义)

    void test(void*)
    {
        //...
    }
    

    有 1 个参数,一个 void * 类型的对象(注意指针总是完整的类型),不在函数中使用。

    此声明在 C++ 中有效,但在 C 中无效,因为在 C 中,具有参数类型列表的函数声明中的每个函数参数同时是其定义都应具有标识符,除非在以下情况下使用了void 参数,如上面引用中所述。

    在 C 中,只有当声明与其定义的类型不同时,才能使用这样的声明。

    所以在 C 中你可以这样写

    void test(void*); // declaratipon
    

    然后

    void test( void *ptr ) // declaration and definition
    {
        //...
    }
    

    【讨论】:

    • "有 1 个参数,一个 void * 类型的对象" -- 它不一定是一个对象
    • @nicomp 指针是对象。例如在 C 中,对象被定义为“执行环境中的数据存储区域,其内容可以表示值”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2017-07-13
    • 2021-11-19
    • 2011-12-04
    相关资源
    最近更新 更多