提问人:mrn 提问时间:9/4/2023 最后编辑:Vlad from Moscowmrn 更新时间:9/4/2023 访问量:100
在 C 语言中定义函数指针?
Defining function pointer in C?
问:
- 最近,我发现了一种用 C 语言定义函数指针的令人惊讶的方法:
typedef void (func_type)(void);
func_type *func_ptr;
这是定义函数指针的正确方法吗?
- 如果我们func_obj定义如下,这个对象的类型是什么,这个对象可以用来做什么?
#include <stdio.h>
typedef void (func_type)(void);
func_type *func_ptr;
func_type func_obj;
int main()
{
printf("Size of func_obj: %zu\n", sizeof func_obj);
printf("Size of func_ptr: %zu\n", sizeof func_ptr);
return 0;
}
代码打印:
Size of func_obj: 1
Size of func_ptr: 8
答:
这是定义函数指针的正确方法吗?
是的。
我更喜欢定义一个函数类型,然后使用它。立即可见的是指针,vs 隐藏了该信息。*
func_type *
typedef void (*func_type)(void); func_type func;
func_obj如下,如果这个对象是什么类型?
func_obj
从字面上看是一个函数。考虑:
#include <stdio.h>
typedef void func_type(void);
// forward declaration of a function
void func_obj(void);
// typedef is just an alias, exactly the same as above
func_type func_obj;
// for function definition, we have to use a ()
void func_obj(void) {
printf("Inside func_obj\n");
}
int main() {
func_obj();
}
从技术上讲,做是无效的 - 'sizeof (函数名称)' 返回什么?.sizeof(func_obj)
这个对象可以用来做什么?
好吧,就像一个函数,用于调用它。Alias 可用于使函数类型保持同步。
这些声明
typedef void (func_type)(void);
func_type *func_ptr;
类似于声明,例如
typedef int T;
T *int_ptr;
因此,为函数类型引入别名的 typedef 没有任何问题。
请注意,这个 typedef 声明
typedef void (func_type)(void);
相当于
typedef void func_type(void);
本声明
func_type func_obj;
声明一个名称为 的函数。func_obj
void( void )
例如,这样的声明允许在一行中列出函数,而不重复其参数列表。
本声明
printf("Size of func_obj: %zu\n", sizeof func_obj);
根据 C 标准,它是无效的,因为您不能将运算符应用于函数。sizeof
来自 C 标准(6.5.3.4 大小和对齐运算符)
1 sizeof 运算符不应应用于具有 函数类型或不完整类型,到括号内的名称中。 类型,或指定位字段成员的表达式。这 alignof 运算符不得应用于函数类型或 不完整类型。
但是,某些编译器可以有自己的扩展,这与 C 标准相矛盾。
评论
这是定义函数指针的正确方法吗?
是的。有两种不同的编码风格:
要么是一个函数,并将一个对象声明为指向该函数的指针:;
typedef
typedef void func_t (void); ... func_t* fptr;
或者将指针隐藏在 :
typedef
typedef void (*func_t) (void); ... func_t fptr;
使用哪一个主要是偏好问题。
前者使函数指针的行为与对象指针一样,因此它有利于一致性和我个人推荐的内容。将指针隐藏在 .好的代码应该是自记录的。typedef
后者在历史上是最常见的,您也应该了解它。在我转换为以前的风格之前,我也使用了很长时间。
如果我们func_obj定义如下,这个对象的类型是什么,这个对象可以用来做什么?
它声明一个函数类型。这是另一个危险的 GNU C 问题 - 你不能在符合 C 的函数上应用(参见约束 6.5.3.4)。gcc 和 clang 在这里显然是不合格的,除非你添加 .sizeof
-pedantic
至于这个“功能”的目的是什么......与任何其他此类稍微有用的 GNU C 特性一样:为了实现新特性而实现。我在任何地方都找不到任何理由或解释来解释这个“功能”实际上有什么好处。它的坏处是显而易见的:它降低了操作员的类型安全性。sizeof
评论
sizeof
评论
sizeof
typeof(void(void))* func_ptr;
func_obj
typedef