假设我们有一个类型为void (*func_ptr)()
的函数指针func_ptr
,那么我们知道使用这个指针我们可以调用函数:
(*func_ptr)();
func_ptr();
但是,假设我们有一个指向整数数组int (*arr_ptr)[5]
的指针,那么为什么我们不能将该数组称为arr_ptr[]
,因此其元素为arr_ptr[0]
, arr_ptr[1]
等?为什么只能用(*arr_ptr)[0]
和(*arr_ptr)[1]
呢?
arr_ptr[0]
的类型为int [5]
;(*arr_ptr)[0]
的类型为int
。如果您愿意,您可以使用arr_ptr[0][0]
。
#include <stdio.h>
int main(void) {
int (*arr_ptr)[5];
int a[2][5] = {{1, 2, 3, 4, 5}, {11, 12, 13, 14, 15}};
arr_ptr = a;
printf("%d %dn", (*arr_ptr)[2], arr_ptr[1][2]);
return 0;
}
你可以看到代码"running"在ideone.
函数指针可以以任何一种方式使用,这只是(nice)单一的糖。
根据ISO/IEC 2011 6.3.2.1/4
A function designator is an expression that has function type. Except when
it is the operand of the sizeof operator, the _Alignof operator,65)
or the unary & operator, **a function designator with type
‘‘function returning type’’ is converted to an expression that has
type ‘‘pointer to function returning type’’ ** .
6.7.6.3 Function declarators
又用长度表示了
这是什么意思呢?当我们用声明符调用函数时,它被转换为该类型的指针,因此两者需要表示相同的函数。即foo和&foo是相同的。你怎么检查这个?我做这件事的愚蠢方法是(请不要这样做)
int s(){return 100;}
int a = &s;
int a = s;
现在都给出相同的错误!
现在你的问题
"我们有一个指向整型数组的指针"这意味着它的类型是int (*)[]
,所以当我们想要访问第二个元素时,例如,我们需要(*ptr)[1]
。//@1
同样的规则也适用于函数指针,例如
int (*p)(void) //`p` pointer to function type
现在假设可以有函数数组(这是不能的),并且需要一个指向这种类型的数组的指针,则需要
--> `int ((*fp)[5])(void)` //which is not possible but lets assumme we can,
则需要访问第二个函数,例如,作为(*fp)[1]
。这与@1类似。
但是按照标准是
函数声明符被转换为指向该类型函数的指针,这意味着
如果我们有一个函数,比如
int foo()
{
return 100;
}
我们可以通过以下方式调用这个函数
1) foo()
2) (&foo)()
3) (*foo)()
1)
和2)
与3)
相同,因为1)被转换为3)
(如标准),而对于2)
, int (*fp)(void) = &foo
可能与int (*fp)(void) = foo;
相同