Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言函数指针语法_C_Function Pointers - Fatal编程技术网

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语言。如果没有进一步的信息,就不能安全地假设任何其他情况。相关: