C 如何为结构中的函数指针成员赋值

C 如何为结构中的函数指针成员赋值,c,pointers,function,struct,C,Pointers,Function,Struct,我可以像这样分配任务 struct a { int (*ptr1)(); int (*ptr2)(); int data; }; typedef struct { struct a x; }all; int fun1() { return 5; }; int fun2() { return 9; }; 是否有其他方法分配这些函数指针? 可以这样分配吗 all *mem = (all*)malloc(sizeof(all)); mem->x.ptr1 = f

我可以像这样分配任务

struct a
{
  int (*ptr1)();
  int (*ptr2)();
  int data;
};

typedef struct
{
  struct a x;
}all;

int fun1()
{
  return 5;
};

int fun2()
{
  return 9;
};
是否有其他方法分配这些函数指针? 可以这样分配吗

all *mem = (all*)malloc(sizeof(all));

mem->x.ptr1 = fun1;
mem->x.ptr2 = fun2;
不,这是不可能的(我假设您实际上是指以下内容,因为您的代码没有多大意义)

这在语法上是正确的,但引用了C标准:

可能有未命名的 在结构对象内填充,但不在其开头填充

这意味着您不能保证
((void**)和mem->ptr1)+1==((void**)和mem->ptr2)

你发布的声明

((void **)&mem->ptr1)[0]=fun1;
((void **)&mem->ptr1)[1]=fun1;
实际上意味着

(void **)mem->ptr1[0] = fun1;
它尝试为函数指针编制索引

请注意,根据您的定义,所有引用(如
mem->ptr1
等)实际上都应该是
mem->x.ptr1

不,这是不可能的(我假设您实际上是指以下内容,因为您的代码没有多大意义)

这在语法上是正确的,但引用了C标准:

可能有未命名的 在结构对象内填充,但不在其开头填充

这意味着您不能保证
((void**)和mem->ptr1)+1==((void**)和mem->ptr2)

你发布的声明

((void **)&mem->ptr1)[0]=fun1;
((void **)&mem->ptr1)[1]=fun1;
实际上意味着

(void **)mem->ptr1[0] = fun1;
它尝试为函数指针编制索引


请注意,根据您的定义,所有引用(如
mem->ptr1
等)实际上应该是
mem->x.ptr1

不,您不能这样分配,原因有很多:

  • 函数指针不兼容 使用
    void*
    。你的编译器可能会 允许这样做,但这是未定义的 根据标准的行为
  • 通过使用
    [0]
    [1]
    您就不会对其进行指针运算 一个
    void
    指针,这是不允许的 要么

  • 同样在第一个有效的示例中,您指定了一个指向函数的指针。这和您所做的一样没有问题,因为如果您不在函数求值为其地址后放置
    ()
    ,则函数将失效。但我仍然发现在这种情况下编写
    &f
    更清晰。

    不,您不能这样分配,原因有很多:

  • 函数指针不兼容 使用
    void*
    。你的编译器可能会 允许这样做,但这是未定义的 根据标准的行为
  • 通过使用
    [0]
    [1]
    您就不会对其进行指针运算 一个
    void
    指针,这是不允许的 要么

  • 同样在第一个有效的示例中,您指定了一个指向函数的指针。这和您所做的一样没有问题,因为如果您不在函数求值为其地址后放置
    ()
    ,则函数将失效。但我仍然发现在这种情况下编写
    &f
    更为清晰。

    这应该是可行的。到底出了什么问题?你有错误信息吗?哪个编译器?还有,你为什么要这样做?@Patrick谢谢Patrick,你能解释一下这些语句吗?@Ben我有一些旧代码,他们在其中编写了这样的代码。但是当我试图编译时,我得到了一些错误…对不起,我有一个印象,您的第一个示例没有编译。您的第一个代码确实是正确的。第二个不是。检查jpalecek的答案。这应该有效。到底出了什么问题?你有错误信息吗?哪个编译器?还有,你为什么要这样做?@Patrick谢谢Patrick,你能解释一下这些语句吗?@Ben我有一些旧代码,他们在其中编写了这样的代码。但是当我试图编译时,我得到了一些错误…对不起,我有一个印象,您的第一个示例没有编译。您的第一个代码确实是正确的。第二个不是。检查jpalecek的答案。