Указатель на функцию Prototype - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь понять, что означают эти прототипы

1.int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                 int (*fpCalculation[3]) (const char *));

2.int* (*fpData[2])(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                     int (* fpCalculation[3]) (const char *));

3.int* (*(*fpData)(const char *))(int (*paIndex)[3] , 
                                 int (* fpMsg) (const char *), 
                                 int (* fpCalculation[3]) (const char *));

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Сначала вы должны найти фактическую переменную, которая объявляется. Во всех трех примерах это fpData. Затем вы должны начать читать объявление, начиная с этой переменной, перемещаясь изнутри наружу.

Итак, давайте начнем с первого примера. Мы видим fpData, поэтому мы говорим "fpData is ...", затем мы видим "*" перед "fpData", поэтому мы говорим "fpData является указателем на ...", затем мы видим объявление типа функции вне *fpData, поэтому мы говорим "fpData - указатель на функцию ...". Затем мы должны прочитать типы аргументов и результат этой функции.

Ну, вы можете читать типы для всех 3 аргументов без проблем. Это:

  • "paIndex - указатель на массив длиной 3 дюйма"
  • "fpMsg - указатель на функцию от const char * до int"
  • "fpCalculation - массив длиной 3 указателя для работы от const char * до int"

В последнем аргументе вы должны заметить, что [3] имеет более высокий приоритет, чем "*". Я имею в виду, что при чтении декларации изнутри наружу вы должны прочитать сначала массив, а затем указатель. И. е. int *a[3] - это "a это массив длиной 3 из указателей типа int", а не "указатель на массив".

Предполагая, что все это, я думаю, вы можете прочитать 2-е объявление без проблем.

Теперь вы должны изучить это: тип результата функции записывается вне (т.е. ДО и ПОСЛЕ) всего остального.

Давайте рассмотрим это:

char (*(*fp)(int))(double)

Что это значит? Что ж, давайте начнем читать: «fp - указатель на функцию, которая принимает int и возвращает ... что?» Ну, мы уже прочитали (*fp)(int) часть. Теперь мы хотим прочитать все остальное. И мы хотим понять, какой тип результата мы уже прочитали. И теперь мы должны отметить, что результатом функции является то, что написано ВНЕ (т. Е. ДО и ПОСЛЕ) всего остального, т.е. е. за пределами того, что мы уже прочитали.

Итак, мы прочитали (*fp)(int). Все остальное, я. е. char (*XXX)(double) - это тип возвращаемого значения для функции, которую мы уже прочитали. Итак, давайте продолжим читать. Наконец мы получим это:

"fp - указатель на функцию, которая получает int и возвращает указатель на функцию, которая получает double и возвращает char".

Теперь вы можете читать 3-ю декларацию без проблем

0 голосов
/ 27 апреля 2018

Ссылка C тарабарщина ↔ Английский , которую выложил chux, все еще выглядит как бред мне. Поэтому я постараюсь звучать более по-человечески:

int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                 int (*fpCalculation[3]) (const char *));

Здесь указывается указатель на функцию fpData, который возвращает указатель на int. Функция принимает 3 переменные следующих типов:

  1. paIndex - указатель на массив int измерения 3. Это может использоваться для пример, когда у вас есть это:

    void bar(int (*paIndex)[3])
    {
    }
    
    void foo(void)
    {
        int fields[5][3] = { {1,1,1}, ... };
    
        bar(fields);
    
    }
    
  2. fpMsg - это указатель функции, который возвращает int. Функция занимает один только аргументы, const char* (в основном строка).

  3. fpCalculation - массив измерений 3 указателей на функции, которые возвращают int. Функции принимают только аргумент: a const char*.

Это зверь указателя на функцию, он работает в такой среде:

#include <stdio.h>

int msg(const char *name)
{
    printf("msg: %s\n", name);
    return 0;
}

int abc1(const char *name)
{
    printf("abc1: %s\n", name);
    return 0;
}

int abc2(const char *name)
{
    printf("abc2: %s\n", name);
    return 0;
}

int *scary_function(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                     int (*fpCalculation[3]) (const char *))
{

    fpMsg("fpMsg");
    fpCalculation[0]("fpCalculation0");
    fpCalculation[1]("fpCalculation1");
    fpCalculation[2]("fpCalculation2");

    for(int i = 0; i < 4; ++i)
    {
        for(int j = 0; j < 3; ++j)
        {
            printf("%-3d ", paIndex[i][j]);
        }
        puts("");
    }

    return NULL;
}

void foo(void)
{
    int matrix[4][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12} };

    int (*fpcalcs[3])(const char*) = { msg, abc1, abc2 };

    int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                     int (*fpCalculation[3]) (const char *));


    fpData = scary_function;

    // calling the function through the function pointer

    fpData(matrix, msg, fpcalcs);
}

int main(void)
{
    foo();
    return 0;
}

Вывод этого

msg: fpMsg
msg: fpCalculation0
abc1: fpCalculation1
abc2: fpCalculation2
1   2   3   
4   5   6   
7   8   9   
10  11  12  

Итак, я подробно объяснил, как разобрать объявление этих функций указатели. Теперь попытайтесь понять другие 2 самостоятельно, если у вас все еще есть проблемы, оставить комментарий.

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