7

我想初始化一个大小为 5 的指针数组,该数组包含指向没有参数且返回 int 的函数的指针(可以是任何满足这些要求的函数)。

这是我迄今为止尝试过的,但出现语法错误:

int (*func)() fparr[5] = int (*func)();

这种语法有什么问题?

4

8 回答 8

16

如果调用要作为数组默认内容提供的函数func,则

  1. 你最好使用 a typedef,
  2. 你必须使用数组初始化器

考虑:

typedef int (*IntFunc)(void);
IntFunc fparr[5] = { func, func, func, func, func };

或者可读性较差的方式,如果您希望避免typedef

int (*fparr[5])(void) = { func, func, func, func, func };
于 2012-12-28T15:00:07.887 回答
3

因为您实际上并没有初始化函数指针数组...尝试:

int (*fparr[5])(void) = { func1, func2, func3, func4, func5 };
于 2012-12-28T15:00:29.677 回答
2

第1步:

将函数的签名定义为类型FN

typedef int (*FN)();

第2步:

FN用签名定义 5 个函数:

int f1(void) { ; }
int f2(void) { ; }
...

第 3 步:

定义并初始化一个包含 5 个类型函数的数组FN

FN fparr[5] = {f1,f2,f3,f4,f5}

否则

如果您不想定义单独的签名,您可以这样做——如前所述——所以:

 int ((*)fpar []) () = {f1,f2, ...}

如果您在声明时知道数组中的函数数量,则无需编写5,如果您在声明的同一行初始化数组,编译器会为您分配此内存。

于 2012-12-28T15:02:33.687 回答
1

嗯,我来晚了……

#include <stdio.h>

int fun0()
{
    return 0;
}

int fun1()
{
    return 1;
}

int fun2()
{
    return 2;
}

int main(int argc, char* argv[])
{
    int (*f[]) (void) = {fun0, fun1, fun2};
    printf("%d\n", f[0]());
    printf("%d\n", f[1]());
    printf("%d\n", f[2]());
    return 0;
}
于 2012-12-28T15:11:14.087 回答
1

可以使用默认值以另一种方式初始化函数指针数组。


示例代码

   
#include <stdio.h>

void add(int index, int a, int b){
    printf("%d. %d + %d = %d\n", index, a, b, a + b);
}
void sub(int index, int a, int b){
    printf("%d. %d - %d = %d\n", index, a, b, a - b);
}
int main(){
    void (*func[10])(int, int, int) = {[0 ... 9] = add};
    func[4] = sub;
    int i;
    for(i = 0; i < 10; i++)func[i](i, i + 10, i + 2);
}
   
如果你运行上面的程序,你会得到下面的输出。所有元素都使用函数add初始化,但数组中的第 4 个元素分配给函数sub


输出

0. 10 + 2 = 12
1. 11 + 3 = 14
2. 12 + 4 = 16
3. 13 + 5 = 18
4. 14 - 6 = 8
5. 15 + 7 = 22
6. 16 + 8 = 24
7. 17 + 9 = 26
8. 18 + 10 = 28
9. 19 + 11 = 30

于 2015-01-21T07:34:07.553 回答
1

我只是在上面的答案中添加了更多内容。函数指针数组可以由枚举变量索引,显示每个索引的操作类型。看看下面的例子。在这里,我们使用 tyepdef 作为函数指针运算符。然后我们创建一个名为act 的函数指针数组。最后,我们将数组初始化为递增和递减函数。在这种情况下,索引 0 表示递增,索引 1 表示递减。我们不使用这种原始索引,而是使用具有 INCR 和 DECR 的枚举,对应于索引 0、1。

#include<stdio.h>
#include<stdlib.h>

typedef void (*operate)(int *, int);
void increment(int *, int);
void decrement(int *, int);

enum {
   INCR, DECR
    };

 int main(void){

   int a = 5;

  operate act[2] = {increment,decrement};

  act[INCR](&a,1);

  printf("%d\n",a);

  act[DECR](&a,2);

  printf("%d\n",a);
     return 0;
 }

 void increment(int *a, int c){
 *a += c;
 }
 void decrement(int *a, int c){
 *a -= c;
  }
于 2017-12-29T15:53:59.070 回答
0

这是一个显示正确语法的工作示例:

#include <stdio.h>

int test1(void) {
    printf("test1\n");
    return 1;
}

int test2(void) {
    printf("test2\n");
    return 2;
}

int main(int argc, char **argv) {
    int (*fparr[2])(void) = { test1, test2 };

    fparr[0]();
    fparr[1]();

    return 0;
}
于 2012-12-28T15:08:46.770 回答
0

示例代码:

static int foo(void) { return 42; }

int (*bar[5])(void) = { foo, foo, foo, foo, foo };

请注意,类型int (*)()int (*)(void)是不同的类型 - 前者表示具有固定但未指定数量的参数的函数,而后者表示没有参数的函数。

另请注意,C 声明符语法遵循与表达式相同的规则(特别是运算符优先级),因此从内到外读取:

bar表示指向函数 ( bar[5]) 的指针 ( )和数组 ( )。括号是必要的,因为后缀函数调用比前缀指针间接绑定更紧密。*bar[5]int (*bar[5])(void)(*bar[5])

于 2012-12-28T15:09:36.700 回答