Выражение массива указателя функции в C - PullRequest
0 голосов
/ 07 февраля 2020

Я C новичок и узнал, что указатель можно выразить в массиве и наоборот. Как *p == p[0], p[1][2] == *(*(p+1)+2) Это приводит к *p[i](arg1, arg2) == p[0][i](arg1, arg2)?

Ответы [ 3 ]

3 голосов
/ 07 февраля 2020

Приводит ли это к * p [i] (arg1, arg2) == p [0] [i] (arg1, arg2)?

Не совсем, *p[i](arg1, arg2) анализируется как *(p[i](arg1, arg2)) - он применяет оператор разыменования * к результату вызова функции.

p[0][i](arg1, arg2) равен (*p)[i](arg1, arg2).

2 голосов
/ 07 февраля 2020

Функциональные указатели ведут себя так же, как обычные объектные указатели. Массив, используемый в выражении, превратится в указатель (, а не наоборот!), Что позволяет нам использовать оператор [], который, в свою очередь, требует, чтобы левый операнд был указателем.

Это объясняется здесь: Поддерживают ли указатели «индексацию стиля массива»?

Проблема с указанным вами c кодом заключается в том, что постфиксные операторы, такие как [], имеют приоритет над унарные операторы, такие как *. Это означает, что (*p)[i](arg1, arg2) эквивалентно p[0][i](arg1, arg2). Последнее явно предпочтительнее, поскольку оно гораздо более читабельно.

2 голосов
/ 07 февраля 2020

Обучение программированию предполагает много экспериментов. Крошечная программа ниже показывает, что ваше предположение *p[2] == p[0][2] неверно.

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

и результат:

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

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

Такие эксперименты дадут вам больше понимания этой топи c чем 1000 онлайн вопросов. Приложите некоторые усилия в вашем обучении. Если вы чего-то не понимаете - напишите что-то вроде этого и посмотрите, как это работает.

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