-1

i am trying to figure out what those prototypes mean

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 *));
Hamdy Fouad
  • 31
  • 1
  • 9
  • 2
    Save time and visit [C gibberish ↔ English](https://cdecl.org/?q=int*+%28*fpData%29%28int+%28*%29%5B3%5D%2C+int+%28*+%29+%28const+char+*%29%2C+int+%28*%5B3%5D%29+%28const+char+*%29%29%3B) to get "fpData as pointer to function (pointer to array 3 of int, pointer to function (pointer to const char) returning int, array 3 of pointer to function (pointer to const char) returning int) returning pointer to int". – chux - Reinstate Monica Apr 26 '18 at 21:45
  • @chux still looks like gibberish to me :) – Pablo Apr 26 '18 at 22:20
  • What have you come up with so far? – nicomp Apr 26 '18 at 23:01
  • 1
    The [Clockwise/Spiral Rule for reading declarations](http://c-faq.com/decl/spiral.anderson.html) is useful. For example, `long* (*x[10][15])(int);` gets parsed as `x`, `[10][15]`, `(*)`, `(int)`, `long*`. That is, `x` is an array of 10 arrays of 15 pointers to functions requiring 1 `int` parameter and returning a pointer to `long`. Another suggestion is the ["right-left" rule](https://stackoverflow.com/a/16265389/539810), where you read things to the right first, then to the left, treating parentheses as grouping symbols as usual (i.e. starting from the inside and working toward the outside). –  Apr 27 '18 at 02:44

4 Answers4

3

First you should find actual variable which is being declared. In all 3 examples this is fpData. Then you should start to read declaration staring from this variable moving from inside to outside.

So, let us begin with first example. We see fpData, so we say "fpData is...", then we see "*" before "fpData", so we say "fpData is pointer to...", then we see function type declaration outside of *fpData, so we say "fpData is pointer to function...". Then we should read types of arguments and result of this function.

Well, you can read types for all 3 arguments without problems. They are:

  • "paIndex is pointer to array of length 3 of ints"
  • "fpMsg is pointer to function from const char * to int"
  • "fpCalculation is array of length 3 of pointers to function from const char * to int"

In the last argument you should note that [3] has the higher priority than "*". I mean that while reading declaration from inside to outside you should read first array and then pointer. I. e. int *a[3] is "a is array of length 3 of pointers of int" and not "pointer to array".

Assuming all this I think you can read 2nd declaration without problems.

Now you should learn this: type of function result is written outside (i. e. BEFORE AND AFTER) of everything else.

Let us consider this:

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

What this means? Well let's start reading, "fp is pointer to function which takes int and returns... what?" Well, we already have read (*fp)(int) part. Now we want to read everything else. And we want to understand what is result type of function we already read. And now we should note that result of function is the thing which is written OUTSIDE (i. e. BEFORE and AFTER) of everything else, i. e. outside of what we already read.

So, we have read (*fp)(int). Everything else, i. e. char (*XXX)(double) is return type for function we already read. So, well, let's continue reading. Finally we will get this:

"fp is pointer to function which gets int and returns pointer to function which gets double and returns char".

Now you can read 3rd declaration without problems

1

The C gibberish ↔ English link that chux posted still looks like gibberish to me. So I'll try to sound more human:

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

This declares a function pointer fpData that returns a pointer to int. The function takes 3 variables of the following types:

  1. paIndex is a pointer to an int array of dimension 3. This can be used for example when you have this:

    void bar(int (*paIndex)[3])
    {
    }
    
    void foo(void)
    {
        int fields[5][3] = { {1,1,1}, ... };
    
        bar(fields);
    
    }
    
  2. fpMsg is a function pointer that returns an int. The function takes one arguments only, a const char* (a string basically).

  3. fpCalculation is an array of dimension 3 of function pointers that return int. The functions take on argument only: a const char*.

This is a beast of a function pointer, it works in an evironment like this:

#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;
}

The output of this is

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

So I've explained in detail how to parse the declaration of these function pointers. Now try understanding the other 2 yourself, if you still have problems, post a comment.

Pablo
  • 13,271
  • 4
  • 39
  • 59
1

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

Here, fpdata is pointer to a function which takes three arguments and returns a pointer to an integer. The arguments are as follows:

  1. pointer to 3 elements integer array,
  2. pointer to a function which takes const char pointer as an argument and return type int,
  3. array of 3 function pointers and each function takes const char pointer as an argument and return type is int

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

In this case, fpdata is array of 2 function pointers, and each function takes three arguments -

  1. pointer to 3 elements integer array,
  2. pointer to a function which takes const char pointer as an argument and return type int,
  3. array of 3 function pointers and each function takes const char pointer as an argument and return type is int

The return type is a pointer to an integer

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

Finally, fpdata is a pointer to a function which takes three arguments -

  1. pointer to 3 elements integer array,
  2. pointer to a function which takes const char pointer as an argument and return type int,
  3. array of 3 function pointers and each function takes const char pointer as an argument and return type is int

The return type is a function pointer which takes const char pointer as argument and return type is pointer to an integer.

cirrusio
  • 580
  • 5
  • 28
0
int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                 int (*fpCalculation[3]) (const char *));

it is function prototype declaration.

Where fpData is a function name, function that takes three arguments:

  1. int (*paIndex)[3]
  2. int (* fpMsg) (const char *)
  3. int (*fpCalculation[3]) (const char *)

…and returns a function pointer [pointer to a function that take no argument but returns pointer to an integer].

Details :: Given function can be written as below

typedef  int* (*ret_func_ptr) ();

ret_func_ptr (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), 
                 int (*fpCalculation[3]) (const char *));
Obsidian
  • 3,719
  • 8
  • 17
  • 30