int(* f [])(int *)代表什么?

时间:2015-08-22 12:46:11

标签: c

这是考试问题之一,目标是确定该课程的内容。我对int (*f[])(int*) = {f1, f2, f2, f1 };是什么感到困惑。我教过它可能是一个数组,其元素是括号中函数的结果,那些结果是指向int的地址。

你能解释一下吗?

同样,函数f[i++]进入的参数是什么参数

for (i=0; i<2; a += fx(f[i++], a));

问题:

int f2(int *p) { return *p-- + 2; }

int f1(int *q) { return ++*q; }

int fx(int (*pf)(int*), int q) {
    int t = q;
    while ((t = pf(&q)) % 2) q+=2;
    return t;
}

#include <stdio.h>

void main() {
    int a = 4, b = 3, *p = &b, i;
    int (*f[])(int*) = {f1, f2, f2, f1 };

    for (i=0; i<2; a += **fx(f[i++]**, a));
    printf("%d", a + *p);
}

7 个答案:

答案 0 :(得分:11)

应用clockwise/spiral rule

int (*f[])(int*)
      ^                f is

int (*f[])(int*)
      ^^^              f is an array

int (*f[])(int*)
    ^^^^^^             f is an array of pointers

int (*f[])(int*)
    ^^^^^^^....^       f is an array of pointers to functions


int (*f[])(int*)
    ^^^^^^^^^^^^       f is an array of pointers to functions
                       that accept a pointer to int

int (*f[])(int*)
^^^^^^^^^^^^^^^^       f is an array of pointers to functions
                       that accept a pointer to int and return a int value

答案 1 :(得分:4)

它将f声明为函数指针数组,返回int并将int *作为参数。

有一个用于理解复杂声明的优先规则,这在Expert C Programming: Deep C Secrets一书中讨论过:

  

理解C声明的优先规则

     
      
  • 一个。通过从名称开始然后按优先顺序阅读来读取声明。

  •   
  • B中。优先级从高到低依次为:

  •   
     
    
        
  • B.1。括号将声明的部分组合在一起

  •     
  • B.2。后缀运算符:
        括号()表示功能,和
        方括号[]表示数组。

  •     
  • B.3。前缀运算符:
        星号表示“指向”。

  •     
  
     
      
  • ℃。如果const和/或volatile关键字位于类型说明符旁边(例如intlongetc。),则它适用于类型说明符。否则,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     

我建议在某些情况下避免使用螺旋规则fails,例如int* a[10][15];

答案 2 :(得分:2)

让我们在令人敬畏的C gibberish to English website

的帮助下将其分开
int (*f[])(int*)
  

将f声明为指向函数的指针数组(指向int的指针),返回int

f是一个函数指针数组。

因此,使用{}数组初始值设定项将函数存储在其中非常清楚。

答案 3 :(得分:1)

与通常的教学方法不同,我建议你从外部开始。识别声明的一般结构并进行细化:替换粗粒度的&#34; blob&#34;你看到更详细的。换句话说,将语法从语法树的根遍历到叶子,而不是试图挑选出正确的叶子并自下而上。

声明的一般结构(具有单个声明者)是:

TYPE WHATEVER;

WHATEVER正在宣布,与TYPE相关。

现在请注意TYPEint,因此WHATEVER的类型为intWHATEVER具有一般形状(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是不是[...]?这是因为类型构造运算符[...]在语法上类似于后缀数组索引运算符*,构造*的类型类似于解除引用的一元运算符*X[]。一元运算符比后缀运算符具有更低的先行。当我们看到*(X[])时,我们知道它意味着(*X)[]而不是*X。符号 declaration | | +------------+ +----------------+ | | specifier-qualifier list -- TYPE declarator -- WHATEVER | | | int +-----+ | | | function -- W1 params -- W2 | | pointer -- W3 (int *) | array -- f 不会在该短语中形成句法单位。如果我们想要第二个含义,我们必须使用括号。

语法树是:

W3

C这样的有用符号只是我们从根到叶子遍历时节点的标签。在f声明中声明的名称位于树的底部,与其他语言不同。随着更深入进入树,我们实际上正在出现 out 类型,所以当我们到达底部时,我们知道最重要的事情:{{1}正在被声明,总的来说它是一个数组。

答案 4 :(得分:0)

the clockwise/spiral rule之后,我们将看到f是一个指向函数的指针数组,其中数组中的每个函数都采用int*参数并返回int

初始化只是用一些函数指针初始化这个数组。

知道f是什么应该有助于解决另一个问题。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

它实质上定义了一个函数指针数组。以下内容:

int (*f[])(int*) = {f1, f2, f2, f1};

将定义与数组初始值设定项相结合。这就是为什么你可以省略数组的大小,因为它是从初始化器推导出来的。每个元素的类型是:

int (*)(int*)

是函数的函数指针,它接受一个int *类型的参数并返回int

for循环的主体由空语句组成。为了更清晰,您可以重写它:

for (i = 0 ; i < 2; a += fx(f[i++], a))
    ;

i = 0i = 1有两次迭代。每次a由函数调用的结果递增:

fx(f[i++], a)

第一个参数是函数的地址,存储在f数组中。它分别是f[0]f[1](即f1f2)。您可以使用等效形式:

fx(&f[i++], a)

但没有真正的区别(这只是偏好问题)。

如果它看起来太奇怪或太复杂,那么您可以将for循环重写为:

for (i = 0 ; i < 2; a += fx(f[i], a), i++)
    ;

以及:

for (i = 0 ; i < 2; i++)
    a += fx(f[i], a);