Как я могу назначить значения для функции, указывающей на членов в структуре - PullRequest
0 голосов
/ 20 августа 2010
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;

Есть ли другой способ назначить эти указатели функций?Можно ли назначить так?

all *mem;

(void **)mem->ptr1[0] = fun1; 
(void **)mem->ptr2[1] = fun2;

Ответы [ 2 ]

5 голосов
/ 20 августа 2010

Нет, это невозможно (я предполагаю, что вы на самом деле имели в виду следующее, поскольку ваш код не имеет особого смысла)

((void **)&mem->ptr1)[0]=fun1;
((void **)&mem->ptr1)[1]=fun1;

Это синтаксически правильно, но цитируем стандарт C:

В объекте структуры может быть безымянный отступ, но не в его начале.

, что означает, что вам не гарантируется, что ((void **)&mem->ptr1)+1 == ((void **)&mem->ptr2).

Выписанное вами заявление

(void **)mem->ptr1[0] = fun1;

фактически означает

(void **)((mem->ptr1)[0]) = fun1;

, который пытается индексировать указатель на функцию.

Обратите внимание, что все ссылки, такие как mem->ptr1 и т. д., должны действительнобыть mem->x.ptr1 в соответствии с вашими определениями.

1 голос
/ 20 августа 2010

Нет, вы не можете назначить так по многим причинам:

  1. функциональные указатели не совместимы с void*.ваш компилятор может разрешить это, но это неопределенное поведение в соответствии со стандартом
  2. Используя [0] и [1], вы не используете арифметику указателей для указателя void, что также недопустимо.

Также в вашем первом работающем примере вы назначаете указатель на функцию.Это нормально, как вы сделали, так как функция, если вы не ставите () после того, как она оценивает ее адрес.Но все же я нахожу более понятным написать &f в таком случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...