Подтвердить что ты не робот

Значение сложного синтаксиса C

Возможный дубликат:
Что означает этот оператор C?

Что означает это выражение?

char *(*c[10])(int **p);
4b9b3361

Ответ 1

c - это массив из 10 указателей функций, которые возвращают char* и принимают int** в качестве аргумента.

(*c[10])
   ^^^^ = array of 10

(*c[10])
 ^ = function pointer

Итак, теперь у нас есть массив из 10 указателей на функции.

char *(*c[10])
^^^^^^ = returns a char*

char *(*c[10])(int** p)
               ^^^^^ = takes a int** as an argument

Массив из 10 указателей функций, которые возвращают a char* и принимают a int** в качестве аргумента.

ПРИМЕЧАНИЕ. Если вы пишете такой код, вы заслуживаете того, чтобы его ударили по лицу.

Ответ 2

cdecl - отличный инструмент для перевода C gibberish на английский

$ cdecl explain 'char * (*c[10]) (int **)'
declare c as array 10 of pointer to function (pointer to pointer to int) returning pointer to char

Ответ 3

Некоторые примеры и фрагмент в конце, который использует decl.

1. Указатель на функцию:

void (*foo)(void);

Дает вам указатель на функцию foo, который не принимает никаких параметров и ничего не возвращает.

Ex. A:

void fun_1(void)
{
    ...
}

foo = fun_1;
foo(); /* this would call fun_1() */

Ex. В:

char (*bar)(int);

Дает вам указатель на функцию bar, который принимает 1 параметр как целое и возвращает a char.

char fun_2(int x)
{
    if (x == 50)
        return 'a';
    return 'Z';
}

char v;
bar = fun_2;
v = bar(50); /* this would call fun_2() with 50 as parameter and return 'a' */

2. Указатель на указатель

int **p; - указатель, указывающий на указатель типа int.

Ex. C:

int y[3] = {4, 3, 6};
int *w = &y[0];
int **z = &w;

printf("print: %d ", **z);
printf("%d ", *++(*z));
printf("%d\n", *(*z+1));

print: 4 3 6

3. Функция, возвращающая указатель

Ex. D:

char *zez(char *s)
{
    s = "def";
    return s;
}


char *str = "abc";

printf("%s - ", str);
printf("%s\n", zez(str));

abc - def

4. Указатель функции на функцию, возвращающую указатель

Создание указателя на zez()

Ex. E:

char *(*ptr_zez)(char *);

ptr_zez = zez;

printf("ptr: %s - ", str);
printf("%s\n", ptr_zez(str));

ptr: abc - def

5. Массив указателей на функции, возвращающий указатель char с помощью указателя char

Ex. F:

char *(*c[10])(char *);

c[0] = zez;

printf("c[0]: %s - ", str);
printf("%s\n", c[0](str));

c[0]: abc - def

6. Msgstr "Объявить c как массив 10 указателя на функцию (указатель на указатель на int), возвращающий указатель на char"

char *cumlade(int **p)
{
    char *c;
    int i;

    if ((c = malloc(sizeof(char) * 7)) == NULL) {
        fprintf(stderr, "Unable to reserve 7 bytes\n");
        exit(0);
    }

    for (i = 0; i < 6; ++i) {
        c[i] = (unsigned char)*(*p+i);
    }
    c[6] = '\0';

    return c;
}

int main(void)
{
    int t[3][3] = {{97 ,98, 99}, {100, 101, 102}};
    int *u = &t[0][0];
    int **v = &u;
    char *ex;
    char *(*c[10])(int **p); /* <-- the fun */

    c[0] = cumlade;
    c[1] = cumlade;    

    ex = c[0](v);
    printf("EX: %s\n", ex);
    free(ex);

    ex = c[1](v);
    printf("AX: %s\n", ex);
    free(ex);

    return 0;
}

EX: abcdef
AX: abcdef

Ответ 4

c - это массив указателей 10 для функций, переводящих указатель на int в качестве своего параметра и возвращающий указатель на char.

Ответ 5

Объявление типа включает три оператора: массив [SIZE], указатель * и функцию (type1 param1, type2 param2, ...). Помните, что все три оператора являются право-ассоциативными.

char *(*c[10])(int **p);

Добавьте более круглые скобки, чтобы сделать ассоциативность более понятной.

char *((*(c[10]))(int *(*p)))

Начните с c, переменной.

c[10] означает, что "c - это массив из 10 элементов, но каждый элемент является..."

Затем см. * рядом с ним. *(c[10]) означает, что "c - это массив из 10 элементов, каждый элемент - указатель, указывающий на..."

Тогда (*(c[10]))(int *(*p)) означает, что "c - это массив из 10 элементов, каждый элемент является указателем на функцию, которая возвращает..." Используя аналогичные методы, мы видим, что функция принимает один параметр, который является "указателем на указатель к int".

Тогда *((*(c[10]))(int *(*p))) означает, что "c - это массив из 10 элементов, каждый элемент является указателем на функцию, которая возвращает указатель на..."

Наконец char *((*(c[10]))(int *(*p))) означает, что "c - это массив из 10 элементов, каждый элемент является указателем на функцию, которая возвращает указатель на char". Что это.

Я считаю, что Правило по часовой стрелке/спираль очень полезно. См. http://c-faq.com/decl/spiral.anderson.html

Но я бы предпочел добавить больше скобок, чем использовать спирали.

Ответ 6

ok теперь ответ, который у вас есть, это массив указателя на функцию, но есть ли чистый (er) способ написать такой код? Да, есть, и я уверен, что этот код можно понять с первого взгляда:

typedef char *(*weirdFuncPtr)(int **p);
weirdFuncPtr funcPtrArray[10];

Btw. обычно я избегаю typdefs - я использую их при объявлении указателей функций. Это облегчает понимание такого кода C (C является аббревиатурой для Cryptic, не так ли?)

Ответ 7

Он объявляет массив указателей функций. В массиве 10 элементов (из части [10] декларации). функция, на которую могут указывать эти указатели, вернет char * и принимает только один параметр. Указатель на указатель на integer (int ** p)

Взгляните на первый ответ на этот вопрос Как я могу использовать массив указателей на функции? там вы найдете еще один пример объявления массива функций-указателей, и это может привести к путанице.

Ответ 8

Если вы ищете интуитивное объяснение этого, http://www.geeksforgeeks.org/archives/16841

Они объяснили это использованием оценки порядка постфикса, как и оценка выражения.