Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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/9/csharp-4.0/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 func(float a1, float a2) { } void (*fptr)(float, float) = &func; 这两行(编译和使用我的编译器)之间有什么区别吗 我想第二个版本只是第一个版本的一个捷径,但我想确保我自己。更重要的是,它是一种标准行为吗?是的,它是一种标准行为,适用于所有C编译器 函数调用实际上总是通过指向函数的指针进行的: 6.5.22“函数调用”: 表示被调用函数的表达式(脚注77)应具有类型指针,指向返回void或

假设有一个函数指针:

void func(float a1, float a2) {

}

void (*fptr)(float, float) = &func;
这两行(编译和使用我的编译器)之间有什么区别吗


我想第二个版本只是第一个版本的一个捷径,但我想确保我自己。更重要的是,它是一种标准行为吗?

是的,它是一种标准行为,适用于所有C编译器

函数调用实际上总是通过指向函数的指针进行的:

6.5.22“函数调用”:

表示被调用函数的表达式(脚注77)应具有类型指针,指向返回void或返回数组类型以外的对象类型的函数

如脚注77所示,当使用函数调用时,“普通”函数标识符实际上转换为函数指针:

脚注77:

通常,这是转换作为函数指示符的标识符的结果

有趣的是,取消引用函数指针(或转换为函数指针的函数指示符)将生成函数的函数指示符,该函数指示符将转换回函数调用表达式的函数指针。因此,您可以取消引用函数指针(或普通函数名),但不必取消引用

6.5.3.2/4“地址和间接运算符”:

就本标准而言,请举例说明:

(*fptr)(1,2);
fptr(1,2);
第二个不是真正的速记-这是编译器所期望的。事实上,第一个例子实际上只是用一种更为冗长的方式来表达与第二个例子相同的内容。但有些人可能更喜欢第一种形式,因为它更清楚地表明正在使用指针。生成的代码中应该绝对没有差异

标准措辞的另一个结果是,您也可以取消引用普通函数名:

func(1,2);
(*func)(1,2);  // equivalent to the above

我想不出这样做有什么正当理由。

他们也这么做

函数调用的前缀始终是指向函数类型的指针表达式

指针类型的表达式,如已声明函数的名称。隐式转换为指向该函数的指针,除非它是一元
“&”
(无论如何都会生成函数的地址)或
sizeof
(这是非法的,而不是生成指针的大小)

该规则的结果是所有这些:

&func
func
*func
**func
它们是等价的。它们的计算结果都是函数的地址,并且它们都可以(如果有适当的括号)用作函数调用的前缀

func(1,2);
(*func)(1,2);  // equivalent to the above
&func
func
*func
**func