C语言函数指针语法
下面是一本旧书的片段:,第二章C语言函数指针语法,c,function-pointers,C,Function Pointers,下面是一本旧书的片段:,第二章 (*(void(*)())0)(); 这相当于更现代的: typedef void (*function_pointer) (); (*(function_pointer)0)(); 我想要一些帮助来更好地理解typedef下面的第二行代码是什么。如何解释这种奇怪的语法?与对象指针(包括指向数组的指针)不同,&和*运算符在使用函数指针时是可选的。有些人还是喜欢使用它们,因为他们认为这样可以使代码对函数指针的使用更加清晰。就我个人而言,我不同意,只使用这些名字
(*(void(*)())0)();
这相当于更现代的:
typedef void (*function_pointer) ();
(*(function_pointer)0)();
我想要一些帮助来更好地理解typedef下面的第二行代码是什么。如何解释这种奇怪的语法?与对象指针(包括指向数组的指针)不同,
&
和*
运算符在使用函数指针时是可选的。有些人还是喜欢使用它们,因为他们认为这样可以使代码对函数指针的使用更加清晰。就我个人而言,我不同意,只使用这些名字
因此:
// given
typedef int (* F) (void);
extern int foo (void);
// the following definitions are all identical:
F fp1 = foo;
F fp2 = &foo;
F fp3 = *foo;
// as are the following call expressions:
foo ();
(&foo) ();
(*foo) ();
fp1 ();
(*fp1) ();
(******* fp1) ();
与数组的情况非常相似,在任何表达式中用作值的函数总是衰减为函数指针,除非用作&
的直接参数。从技术上讲,这也包括函数调用表达式,因此括号左侧的东西始终是函数指针,即使调用直接指向静态命名的函数(即表达式foo()
)。类似地,用*
解除对函数指针的引用会检索函数的“值”,但函数“值”唯一能做的就是立即衰减回指针,这就是为什么可以用任意多的星星解除对它的引用
所有这些在运行时都没有任何效果;它只影响表达式的类型
但是,使用函数指针作为&
的直接参数将执行其他操作:它将创建标准的双指针(指向变量的指针),或者如果函数表达式不是左值,则在语法上无效。您还可以将一级&
粘贴在一些可选星号之前,在这种情况下,它可以防止*
运算符的结果立即衰减,而是显式转换类型,继续完全不起作用
因此,从问题中编写代码的更简单(更清晰)方法如下:
typedef void (*function_pointer) ();
// 1 - direct
((function_pointer)0)();
// 2 - intermediate variable
function_pointer fp = (function_pointer)0;
fp ();
大多数星星什么也不做,没有它们代码更容易阅读。这也表明问题表达式的第二行实际上是两个操作(在机器级别通常都没有操作)-首先它将
0
转换为具有类型函数\u指针
,然后应用*
。(然后在第三个no op中,它再次将*
衰减到括号外。)它表示“将0
转换为函数指针类型并调用此函数”。这是一个跳转到内存地址0
的技巧,在某些系统上有效地导致“热复位”。@Jean-Françoisfare,谢谢:)他们睡觉,虽然..这不是“更现代”,但只是另一种书写方式,可能可读性更好(取决于读者的经验)。这两种构造都调用未定义的行为。这一点也不“奇怪”;这就是C的用法。@EugeneSh:空指针不需要表示“所有位为零”。代码调用UB wrt语言。如果没有进一步的信息,就不能安全地假设任何其他情况。相关: