Как я могу использовать массив указателей функции?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

141
задан The Guy with The Hat 21 May 2014 в 21:43
поделиться

3 ответа

У Вас есть хороший пример здесь (Массив Указателей функции) , с , синтаксис детализировал .

int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);

int (*p[4]) (int x, int y);

int main(void)
{
  int result;
  int i, j, op;

  p[0] = sum; /* address of sum() */
  p[1] = subtract; /* address of subtract() */
  p[2] = mul; /* address of mul() */
  p[3] = div; /* address of div() */
[...]

Для вызова одного из тех указателей функции:

result = (*p[op]) (i, j); // op being the index of one of the four functions
183
ответ дан 23 November 2019 в 23:11
поделиться

Вышеупомянутые ответы могут помочь Вам, но можно также хотеть знать, как использовать массив указателей функции.

void fun1()
{

}

void fun2()
{

}

void fun3()
{

}

void (*func_ptr[3]) = {fun1, fun2, fun3};

main()
{
    int option;


    printf("\nEnter function number you want");
    printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
    scanf("%d",&option);

    if((option>=0)&&(option<=2))
    { 
        (*func_ptr[option])();
    }

    return 0;
}

можно только присвоить адреса функций с тем же типом возврата и теми же типами аргумента и никакими из аргументов единственному массиву указателя функции.

можно также передать аргументы как ниже, если все вышеупомянутые функции имеют то же количество аргументов того же типа.

  (*func_ptr[option])(argu1);

Примечание: здесь в массиве нумерация указателей функции будет запускаться от 0 то же как в общих массивах. Таким образом в вышеупомянутом примере fun1 может быть назван, если option=0, fun2 можно назвать, если option=1 и fun3 можно назвать если option=2.

37
ответ дан 23 November 2019 в 23:11
поделиться

О, существуют тонны примера. Просто взгляните на что-либо в бойком или gtk. Вы видите работу указателей функции в работе там полностью.

Здесь, например, инициализация материала gtk_button.


static void
gtk_button_class_init (GtkButtonClass *klass)
{
  GObjectClass *gobject_class;
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;

  gobject_class = G_OBJECT_CLASS (klass);
  object_class = (GtkObjectClass*) klass;
  widget_class = (GtkWidgetClass*) klass;
  container_class = (GtkContainerClass*) klass;

  gobject_class->constructor = gtk_button_constructor;
  gobject_class->set_property = gtk_button_set_property;
  gobject_class->get_property = gtk_button_get_property;

И в gtkobject.h Вы находите следующие объявления:


struct _GtkObjectClass
{
  GInitiallyUnownedClass parent_class;

  /* Non overridable class methods to set and get per class arguments */
  void (*set_arg) (GtkObject *object,
           GtkArg    *arg,
           guint      arg_id);
  void (*get_arg) (GtkObject *object,
           GtkArg    *arg,
           guint      arg_id);

  /* Default signal handler for the ::destroy signal, which is
   *  invoked to request that references to the widget be dropped.
   *  If an object class overrides destroy() in order to perform class
   *  specific destruction then it must still invoke its superclass'
   *  implementation of the method after it is finished with its
   *  own cleanup. (See gtk_widget_real_destroy() for an example of
   *  how to do this).
   */
  void (*destroy)  (GtkObject *object);
};

(*set_arg) материал является указателем на функцию, и это может, например, быть присвоенным другая реализация в некотором производном классе.

Часто Вы видите что-то вроде этого

struct function_table {
   char *name;
   void (*some_fun)(int arg1, double arg2);
};

void function1(int  arg1, double arg2)....


struct function_table my_table [] = {
    {"function1", function1},
...

, Таким образом, можно достигнуть таблицы по имени и вызвать "связанную" функцию.

Или возможно Вы используете хеш-таблицу, в которой Вы помещаете функцию и зовете ее по имени.

Отношения
Friedrich

2
ответ дан 23 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: