我是编程的新手。我正在阅读的书具有下面的代码...但是它没有解释它。...我的问题是函数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
,则会发生运行时错误。
谁能告诉我为什么?
答案 0 :(得分:3)
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();
之间的区别,您需要了解编译器如何读取声明。
编译器将声明读为:
因此,将以下几点应用于两个声明:
void (*s)();
将其读为粗体: 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