提问人:pushpa 提问时间:9/5/2023 最后编辑:wohlstadpushpa 更新时间:9/5/2023 访问量:83
c 中的 'void *ptr[N](int)' 和 'void (*ptr)[N](int)' 有什么区别?[复制]
What is the differnce between `void *ptr[N](int)` and `void (*ptr)[N](int)` in c? [duplicate]
问:
假设我有 和void (*ptr[3])(int)
void (*ptr)[3](int)
第一个按预期工作。 但是第二个会抛出一个错误。
我都尝试了,但无法找出问题所在。 错误内容如下:
"..错误:将“PTR”声明为函数数组无效 (*ptr)3;”
答:
void (*ptr)[3](int)
与声明为指向函数数组的指针相同,这是不允许的。不能有函数数组。ptr
typedef void(functype)(int);
functype ptr[3]; // error
您最需要的是一个函数指针数组,这是您的工作声明 创建的。void (*ptr[3])(int)
typedef void(functype)(int);
functype* ptr[3];
// ^
使用示例:
void a(int x) {}
void b(int x) {}
void c(int x) {}
int main(void) {
typedef void(functype)(int);
functype* ptr[3] = {a,b,c};
}
评论
void (*ptr)[3](int)
是“指向函数数组的指针”,而不是“函数数组”
typeof(void(int))* ptr[3];
typeof
typedef
无论谁想出了指向函数或数组的指针的语法,背后都没有太多的理由——很可能它只是偶然发生的。这里有一些规则:
函数实际上并不存在于表达式中,只有函数指针才存在。 C17 6.3.2.1 第 4 节:
函数指示符是具有函数类型的表达式。除非它是运算符的操作数或一元运算符,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型”的表达式。
sizeof
&
声明/初始化与表达式中的运算符优先级“协调”。这意味着它始终意味着“3 个 int 指针的数组”,而不是“指向 3 个 int 数组的指针”,就像表达式总是表示“访问第 4 个元素然后取消引用”一样。
int*p[3]
*p[3]
由于上述原因,编译器在面对非法语法时可能很难产生合理的诊断。在这种情况下,错误和错误在 gcc 和 clang 中给出了相同的诊断消息,有点像“将'p'声明为函数数组”。尽管目前尚不清楚后者如何被视为“函数数组”。事实上,前者是函数数组,后者是指向函数数组的指针 - 两者都是不允许的。int p [3] (void);
int (*p) [3] (void);
正如我们所知道的,几乎没有人理解这种混乱,包括那些为 gcc 和 clang 编写编译器诊断的人。少数假装这样做的人是那些愿意花费大量时间按照“顺时针螺旋”解析不必要的晦涩表情的人,直到他们的眼睛看起来像顺时针螺旋......别这样。
这里的 #1 规则是在使用函数指针时始终使用 typedef,没有例外。
这里有一个小小的常见问题解答:
int ptr1 (void); // OK. Function
int (ptr2) (void); // Weird but OK. Still a function
int ptr3 [3] (void); // Invalid declaration - array of functions
int (*ptr4) (void); // OK. Pointer to function
int (*ptr5 [3]) (void); // OK. Array of pointers to functions
int (*ptr6) [3] (void); // Invalid declaration - pointer to array of functions
int ((*(*ptr4)(void))[3]); // Madness, pointer to a function returning a pointer to array of 3 int
强烈推荐的做法:
typedef int func_t (void); // function type
func_t* func; // function pointer
func_t* func[3]; // array of function pointers
func_t* const func = f; // read-only function pointer, can't be reassigned
func_t* const func[3] = // read-only array of function pointers, can't be reassigned
{ ... };
评论
int ((*(*ptr4)(void))[3]);
评论
void *ptr[N](int)