C int(*f[])(int*)代表什么?
这是一道考试题,目的是确定程序将编写什么。我真的很困惑什么是C int(*f[])(int*)代表什么?,c,C,这是一道考试题,目的是确定程序将编写什么。我真的很困惑什么是int(*f[])(int*)={f1,f2,f2,f1}是。我教过它可能是一个数组,它的元素是括号中函数的结果,这些结果是指向int的地址 你能给我解释一下吗 还有,函数f[i++]输入了什么参数 对于(i=0;i下面我们将看到f是一个指向函数的指针数组,数组中的每个函数都取一个int*参数并返回一个int 初始化只是用一些函数指针初始化这个数组 了解f是什么应该有助于解决另一个问题。它将f声明为指向返回int并将int*作为参数的函
int(*f[])(int*)={f1,f2,f2,f1}代码>是。我教过它可能是一个数组,它的元素是括号中函数的结果,这些结果是指向int的地址
你能给我解释一下吗
还有,函数f[i++]
输入了什么参数
对于(i=0;i下面我们将看到f
是一个指向函数的指针数组,数组中的每个函数都取一个int*
参数并返回一个int
初始化只是用一些函数指针初始化这个数组
了解f
是什么应该有助于解决另一个问题。它将f
声明为指向返回int
并将int*
作为参数的函数的指针数组
书中讨论了理解复杂声明的优先规则:
理解C声明的优先规则
- A.通过从名称开始,然后按照优先顺序读取声明
- B.从高到低的优先级为:
- B.1.括号将声明的各个部分组合在一起
- B.2.后缀运算符:
括号()
表示函数,和
方括号[]
表示数组
- B.3.前缀运算符:
表示“指针指向”的星号
- C.如果
const
和/或volatile
关键字位于类型说明符旁边(例如int
、long
、等
),则它适用于类型说明符。否则const
和/或volatile
关键字适用于其最左边的指针星号
因此,它是这样的:
f -- f (A)
f[] -- is an array (B.1)
*f[] -- of pointers to (B.3)
(*f[])( ) -- function (B.2)
(*f[])( int * ) -- that expects a pointer to an int as an argument
int (*f[])( int* ) -- and return an int
我建议避免使用螺旋规则,因为在某些情况下,例如在int*a[10][15];
这种情况下
int (*f[])(int*) = {f1, f2, f2, f1 };
是int(int*)类型的函数指针数组的声明,该数组是具有返回类型int
和一个类型int*
的参数的函数
由于f
是一个数组,因此f[i++]
是数组的一个元素,它具有值f1、f2等之一
此函数
int fx(int (*pf)(int*), int q);
有两个参数:指向int(int*)类型的函数的指针和int类型的对象
所以这个表达式
fx(f[i++], a)
是函数的调用,函数指针f1、f2等的其中一个参数和对象a
让我们借助以下工具来分解它:
将f声明为返回int的函数指针(指向int的指针)数组
f
是函数指针数组
因此,使用{}
数组初始值设定项来存储其中的函数非常清楚。它本质上定义了一个函数指针数组。如下所示:
int (*f[])(int*) = {f1, f2, f2, f1};
将定义与数组初始值设定项相结合。这就是为什么可以忽略数组的大小,因为它是从初始值设定项推导出来的。每个元素的类型为:
int (*)(int*)
它是函数的函数指针,该函数接受一个类型为int*
的参数并返回int
for
循环的主体由空语句组成。为了更清晰,您可以将其重写为:
for (i = 0 ; i < 2; a += fx(f[i++], a))
;
第一个参数是存储在f
数组中的函数地址。它分别是f[0]
和f[1]
(即f1
和f2
)。您可以使用等效形式:
fx(&f[i++], a)
但这并没有什么真正的区别(只是偏好的问题)
如果它看起来太奇怪或太复杂,那么您可以将for
循环重写为:
for (i = 0 ; i < 2; a += fx(f[i], a), i++)
;
for(i=0;i<2;a+=fx(f[i],a),i++)
;
以及:
for (i = 0 ; i < 2; i++)
a += fx(f[i], a);
(i=0;i<2;i++)的
a+=fx(f[i],a);
应用
与通常的教学方法不同,我建议您从外向内开始。识别声明的一般结构,然后进行细化:替换粗粒度的“blob”换句话说,从语法树的根到叶子遍历语法,而不是试图找出正确的叶子,然后自下而上工作
声明(具有单个声明器)的一般结构为:
声明的内容,与类型相关
现在请注意,TYPE
是int
,因此WHATEVER
是int
类型。而WHATEVER
具有一般的形状(W1)(W2)
:括号中有两个语法单位,任意1和任意2:
int (W1)(W2);
这里,W1
是被声明的,它是一个返回int
的函数,它接受一个W2
参数列表。后者实际上表示int*
:
int (W1)(int *);
因此,W1
是一个返回int
的函数,它接受int*
。但是W1
实际上是*W3
,这使得W3
成为指向W1
类型的指针
int (*W3)(int *);
W3
是指向返回int
的函数的指针,该函数接受int*
而W3
实际上是f[]
,因此f
是一个未指定大小的数组,属于W3
的类型:
int (*f[])(int *);
f
是指向返回int
的函数的未指定大小的指针数组,它接受int*
提示:我们如何知道W1
实际上不是W3[]
而W3
则是*f
?这是因为类型构造操作符[…]<
TYPE WHATEVER;
int (W1)(W2);
int (W1)(int *);
int (*W3)(int *);
int (*f[])(int *);
declaration
| |
+------------+ +----------------+
| |
specifier-qualifier list -- TYPE declarator -- WHATEVER
| | |
int +-----+ |
| |
function -- W1 params -- W2
| |
pointer -- W3 (int *)
|
array -- f