void类型返回指针的功能

时间:2019-07-30 07:25:58

标签: c

我是编程的新手。我正在阅读的书具有下面的代码...但是它没有解释它。...我的问题是函数void(*s)()与{{1}有何不同? }

void *s()

如果我将void show(); main() { void (*s)(); s=show; (*s)(); } void show() { printf("something"); } 替换为void(*s)(),则会发生编译时错误,提示void *s() 在线error: lvalue required as left operand of assignment| 并且如果我将s=show;替换为show,则会发生运行时错误。 谁能告诉我为什么?

3 个答案:

答案 0 :(得分:3)

c's operator precedence

void(*s)();

读取为:定义变量s,如果该变量被取消引用,然后将其称为 ,则为空。因此s是指向函数的指针。

void *s();

读取为:声明一个名称s,如果该名称被调用然后取消引用 ,则该名称为空。在取消引用()之前先评估呼叫运营商*。因此s是一个函数。该行仅声明一个不带参数的函数s和一个空指针作为返回值。与第一行void show();相同。只是具有不同的名称和不同的返回值。

无法分配功能

您显然知道,函数是通过附加正文{...}来定义的。 可以分配函数指针,就像其他任何指针一样。 这就是为什么您会收到编译器错误lvalue required as left operand of assignment的原因。它说:“我不允许分配给=的左侧”

让我们看一下代码:

s=show;

s = &show; =>的缩写形式。将函数show的地址分配给指针s。

(*s)();

取消引用指针s,然后调用它。可以缩短为s();

此外: void(*s)();是一个定义,它实际上创建了一个变量,因此您可以为其分配一个值。 void *s();是一个声明,它只是告诉编译器存在一个名为s的元素,而没有创建它。由于未创建任何变量,因此无法分配给它。

答案 1 :(得分:1)

void (*s)()void* s是非常不同的东西。第一个是指向返回空值的 function 的指针(注意声明后的圆括号),第二个只是指向未类型化数据的普通指针。

将第一对括号作为阅读提示。 “ s是指向返回void的函数的指针”,而不是“ s是指向void的指针”

答案 2 :(得分:1)

要了解void (*s)();void * s();之间的区别,您需要了解编译器如何读取声明。

编译器将声明读为:

  1. 从标识符开始
  2. 将声明向右向前移动,直到面对正确的右括号“)”或声明的结尾为止
  3. 将阅读声明的方向向左更改,直到面对左方括号“(”或声明的结尾
  4. 如果声明未完成,请从第2步重复执行

因此,将以下几点应用于两个声明:

  • void (*s)();
    1. 在标识符之后没有任何内容,因为我们遇到了“)”
    2. 指向的指针
    3. 重复编号2,我们将遇到一个功能,该功能不知道接收到的信息
    4. 在权利完成后重复数字3 并返回空值

将其读为粗体 s是指向函数的指针,该函数没有有关其接收的信息,并返回void  -void * s();  1. 是一个  2. 有关接收到的内容的信息的功能在此处已完成  3. 并返回一个指向空的指针,左侧目录在此处完成  4.声明完成

将其读为粗体 s是一个函数,该函数不知道接收的内容,并返回指向void的指针

现在让我们回答您的问题:

  

如果我将void(* s)()替换为void * s(),则会发生编译时错误,提示错误:需要左值作为赋值的左操作数|在lines = show;

正如我们所讨论的,void *s();是一个函数而不是函数指针,并且您不能为函数名称标识符分配值

  

,如果我将show替换为show(),也会发生运行时错误。谁能告诉我为什么?

因为s=show()中的赋值运算符需要分配rvalue,但是您不会从调用函数show中返回任何值。

编辑: 感谢@pmg评论。

void s();和空白s(void);之间有区别

  • void s();是一个没有收到任何信息的函数。
  • void s(void);是什么都不接收的函数。

这两个函数返回void

相关问题