有个问题,请教一下大家

pang123hui 2010-02-22 10:00:43

#include <stdio.h>

void Function()
{
printf("Call Function!\n");
}
int main()
{
void (*p)();
p=Function;
(*p) ();
//(p) ();
//上面两者都能输出Call Function!,那两者有什么不同之处呢???
return 0;
}
...全文
188 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
macrojj 2010-02-26
  • 打赏
  • 举报
回复
加不加 * 对函数指针来说 都是一样调用的函数。

我认为应该和四楼一样吧。 知道函数名之后 还是要找地址。
harold2007 2010-02-26
  • 打赏
  • 举报
回复
4楼的解答很清晰,这个问题确实需要大家讨论讨论
Darain 2010-02-26
  • 打赏
  • 举报
回复
我也觉得四楼说得很好,很清楚,但是习惯用(*p)不是就增加编译器负担了吗?
beautifularea 2010-02-26
  • 打赏
  • 举报
回复
先学习了再说,。。。。。。。
malu_1982 2010-02-26
  • 打赏
  • 举报
回复
引用 7 楼 codefly 的回复:
呵呵,扩展讨论一下这个问题,比如:
int a;
a “指代”的是个整数实体。

struct _B
{
    int  b1;
    int  b2;
} b;
b “指代”的是个结构实体,注意是这个含两个域的struct型实体的全部噢,既不单单是其中的b1,也不单单是其中的b2,是全部噢。

void f()
{
  ....
}
f “指代”是这个函数的所有指令的整体。在普通表达式中,f表示函数中第一条指令的地址值,而在进行小括号操作时,即f(),f是作为“函数整体”的意思的,表示要执行这个函数中一系列指令。

void (*p)();
p “指代”的又是什么呢?只是个函数指针而已。p = f;一句中,f表示函数第一条指令的地址值,赋值给了p。如果我们在设计C编译器时非常“严苛”,那么p就不能直接进行小括号操作,因为它根本不“指代”整个函数嘛。我们必须先对p进行"*"操作,也就是人们常说的dereference操作,得到指代“函数整体”的事物,然后才能进行小括号操作。即(*P)()。如果我们故意把一个int a变量的地址赋值给p,p = (void (*)())&a; 语法上也可以,当然一运行(*P)()就挂了。所以正统的写法是(*P)();不过所幸的是ANSI标准没有这里所说的那么“严苛”了,于是支持p()的简写方式。

所以《C陷阱与缺陷》中才会说:
“(*fp)(); 因为fp是一个函数指针,那么*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp(),但是一定要记住这种写法只是一种简写形式。”


太好了, MARK, 向这位同学学习中!
huanmie_09 2010-02-26
  • 打赏
  • 举报
回复
引用 7 楼 codefly 的回复:
呵呵,扩展讨论一下这个问题,比如:
int a;
a “指代”的是个整数实体。

struct _B
{
    int  b1;
    int  b2;
} b;
b “指代”的是个结构实体,注意是这个含两个域的struct型实体的全部噢,既不单单是其中的b1,也不单单是其中的b2,是全部噢。

void f()
{
  ....
}
f “指代”是这个函数的所有指令的整体。在普通表达式中,f表示函数中第一条指令的地址值,而在进行小括号操作时,即f(),f是作为“函数整体”的意思的,表示要执行这个函数中一系列指令。

void (*p)();
p “指代”的又是什么呢?只是个函数指针而已。p = f;一句中,f表示函数第一条指令的地址值,赋值给了p。如果我们在设计C编译器时非常“严苛”,那么p就不能直接进行小括号操作,因为它根本不“指代”整个函数嘛。我们必须先对p进行"*"操作,也就是人们常说的dereference操作,得到指代“函数整体”的事物,然后才能进行小括号操作。即(*P)()。如果我们故意把一个int a变量的地址赋值给p,p = (void (*)())&a; 语法上也可以,当然一运行(*P)()就挂了。所以正统的写法是(*P)();不过所幸的是ANSI标准没有这里所说的那么“严苛”了,于是支持p()的简写方式。

所以《C陷阱与缺陷》中才会说:
“(*fp)(); 因为fp是一个函数指针,那么*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp(),但是一定要记住这种写法只是一种简写形式。”

不错.
悠然红茶 2010-02-23
  • 打赏
  • 举报
回复
呵呵,扩展讨论一下这个问题,比如:
int a;
a “指代”的是个整数实体。

struct _B
{
int b1;
int b2;
} b;
b “指代”的是个结构实体,注意是这个含两个域的struct型实体的全部噢,既不单单是其中的b1,也不单单是其中的b2,是全部噢。

void f()
{
....
}
f “指代”是这个函数的所有指令的整体。在普通表达式中,f表示函数中第一条指令的地址值,而在进行小括号操作时,即f(),f是作为“函数整体”的意思的,表示要执行这个函数中一系列指令。

void (*p)();
p “指代”的又是什么呢?只是个函数指针而已。p = f;一句中,f表示函数第一条指令的地址值,赋值给了p。如果我们在设计C编译器时非常“严苛”,那么p就不能直接进行小括号操作,因为它根本不“指代”整个函数嘛。我们必须先对p进行"*"操作,也就是人们常说的dereference操作,得到指代“函数整体”的事物,然后才能进行小括号操作。即(*P)()。如果我们故意把一个int a变量的地址赋值给p,p = (void (*)())&a; 语法上也可以,当然一运行(*P)()就挂了。所以正统的写法是(*P)();不过所幸的是ANSI标准没有这里所说的那么“严苛”了,于是支持p()的简写方式。

所以《C陷阱与缺陷》中才会说:
“(*fp)(); 因为fp是一个函数指针,那么*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp(),但是一定要记住这种写法只是一种简写形式。”
lucasma.eth 2010-02-22
  • 打赏
  • 举报
回复
4楼的说法看起来挺有道理, 但不知道编译器实际是不是这样处理的.
个人认为没有必要理会这个, 其实是两种完全等价的写法, LZ可以
根据个人习惯选一种.
悠然红茶 2010-02-22
  • 打赏
  • 举报
回复
《C陷阱与缺陷》举过类似的例子,并做了如下说明:

“(*fp)();
因为fp是一个函数指针,那么*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp(),但是一定要记住这种写法只是一种简写形式。”
smallbear_2008 2010-02-22
  • 打赏
  • 举报
回复
(*p) (); 应该是将函数指针p又转换为函数名,相当于Function();实际上不需要转换,编译器在调用函数前又会把函数名转换为 函数指针。

(p) (); 这就是直接用函数指针了,编译器需要的是 一个指针。

c和指针 上面是这样说的。我习惯于用第一个,更加明确对指针的引用。
stardust20 2010-02-22
  • 打赏
  • 举报
回复
同ls 没什么不同的。。
Zijian_Zhang 2010-02-22
  • 打赏
  • 举报
回复
//(p) ();
p两边可以不带括号。
Zijian_Zhang 2010-02-22
  • 打赏
  • 举报
回复
没什么不同一样的。

这只不过是两种观点的,两个是一样的。

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧