-1

I'm C beginner and I learned a pointer can be expressed in an array and vice versa.
Like *p == p[0], p[1][2] == *(*(p+1)+2)
Does these lead to *p[i](arg1, arg2) == p[0][i](arg1, arg2)?

op ol
  • 705
  • 4
  • 11
  • 1
    It looks like you're trying to use a 2d-array of function pointers. I STRONGLY advice you to reconsider... – klutt Feb 07 '20 at 11:49
  • If I ever ended up having to deal with a 2d-array of function pointers, I would do something like this: `int (*f)(int, int) = p[0][i]; int ret = f(arg1, arg2);` – klutt Feb 07 '20 at 11:54
  • @ klutt nd-pointer and nd-array which have each different memory structure but each expression can be compatible. I wonder is this same for a function pointer? You sad 2d-array of function pointers, when I heard this, I can image only `*p[i][j](arg1, arg2)` – op ol Feb 07 '20 at 12:03
  • @opol pointers and arrays are not compatible (whatever you understand by compatible) - it may look that they are but they are not. – 0___________ Feb 07 '20 at 12:07
  • It seems like you need to read a lot to understand the very basics. `p[i]` is syntactic sugar for `*(p+i)`. Nothin more. Nothing less. Pointers and arrays are two separate things. – klutt Feb 07 '20 at 12:21
  • Related: https://stackoverflow.com/questions/4607128/in-c-are-arrays-pointers-or-used-as-pointers – klutt Feb 07 '20 at 12:26
  • @P__J__ I can't sure my writing is sufficient to show my query. What I wonder is not during coding something that each code is brief example for my question. – op ol Feb 07 '20 at 12:37
  • @opol I voted to close as you need to put some more effort into it to make it clear. – 0___________ Feb 07 '20 at 12:40
  • @klutt Pedantically, `p[i]` is rather syntactic sugar for `*((p)+(i))` which is part of the OP's problem. – Lundin Feb 07 '20 at 12:55
  • @klutt Also, I recall finding a valid use-case for a 2D array of function pointers. I once used that in an embedded system finite state machine, where each state had a state machine of its own. Alas, I was the only one who understood what the code did, so my colleagues urged me to refactor it. I ended up with just an array of function pointers and let each state handle it's own state machine internally. So it was more de-centralized, better OO design... but still, I think this was a valid use-case for the original 2D array. – Lundin Feb 07 '20 at 13:00
  • @Lundin Sure, it exists use cases. But they are very rare. I would say that if you use them often enough to motivate learning the strange syntax instead of using an intermediate pointer, then you're doing something wrong. ;) – klutt Feb 07 '20 at 13:26

3 Answers3

3

Does these lead to *p[i](arg1, arg2) == p[0][i](arg1, arg2)?

Not really, *p[i](arg1, arg2) is parsed as *(p[i](arg1, arg2)) - it applies the * dereference operator on the result of function call.

p[0][i](arg1, arg2) is equal to (*p)[i](arg1, arg2).

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • `p[0][i](arg1, arg2)` is equal to `(*p)[i](arg1, arg2)`. Then Is `(*p)[i](arg1, arg2)` equal to `*((*p)+i)(arg1, arg2)`? – op ol Feb 07 '20 at 12:17
  • `(*((*p)+i))(arg1, arg2)`. The `*` operator has higher precedence then `(` function call operator. The `*((*p)+i)(arg1, arg2)` is the same as `*( ((*p)+i)(arg1, arg2) )` – KamilCuk Feb 07 '20 at 16:13
2

Learning of programming involves a lots experimenting. The tiny program below shows that your assumption *p[2] == p[0][2] is wrong.

#define f(x)  void f ## x(void) {printf("Func = %d\n", x);}

f(10);f(11);f(12);
f(20);f(21);f(22);
f(30);f(31);f(32);


int main()
{
    void (*p[3][3])(void) = {{f10, f11, f12}, {f20, f21, f22}, {f30, f31, f32}};

    for(int x = 0; x < 3; x++)
    {
        for(int y = 0; y < 3; y++)
        {
            printf("%p\t", (void *)p[x][y]);
        }
        printf("\n");
    }

    printf("\np[0][2] = %p\n", (void *)p[0][2]);
    printf("*p[2] = %p\n", (void *)*p[2]); 
}

and the result:

0x4005b2    0x4005cd    0x4005e8    
0x400603    0x40061e    0x400639    
0x400654    0x40066f    0x40068a    

p[0][2] = 0x4005e8
*p[2] = 0x400654

Such a experiments will give you more understanding of this topic than 1000 online questions. Put some effort in your learning. If you do not understand something - write something like this to see how it works.

0___________
  • 60,014
  • 4
  • 34
  • 74
2

Function pointers behave just like ordinary object pointers. An array used in an expression will decay into a pointer (not vice versa!), which allows us to use the [] operator, which in turn requires the left operand to be a pointer.

This is explained here: Do pointers support "array style indexing"?

The problem with your specific code is that postfix operators such as [] take precedence over unary operators such as *. Meaning that (*p)[i](arg1, arg2) is equivalent to p[0][i](arg1, arg2). The latter is clearly preferred since it is far more readable.

Lundin
  • 195,001
  • 40
  • 254
  • 396