что означает линия int * (* (x ) ()) ; делать в C?

Это первый раз, когда я задавал вопрос о переполнении стека, поэтому, пожалуйста, не стесняйтесь сказать мне, что я сделал что-то неправильно или не достаточно конкретно. Я программировал микроcontrollerы на C примерно 4 сейчас. Несколько дней назад я принимал участие в конкурсе электроники. Одним из многих вопросов было то, что именно C-кодовая линия

int *(*(x[3])())[5]; 

делает. Это строка, как я ее помню. Возможно, что скобка была в другом месте, но я думаю, что это была линия.

Я предполагаю, что x – это массив функциональных указателей, из которых мы берем четвертый элемент и разыгрываем его. Затем эта функция выполняется без передачи параметров. Возвращаемое значение, по-видимому, является указателем на указатель, массив которого мы разыскиваем один раз, чтобы получить адрес первого элемента. Затем мы выбираем 6-й элемент этого массива. Я понятия не имею, что такое int, хотя …

Большое спасибо за ответ на мой вопрос и приятный день.

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

 *a[n] -- a is an array of pointer (*a)[n] -- a is a pointer to an array *f() -- f is a function returning a pointer (*f)() -- f is a pointer to a function 

Применяя эти правила, мы получаем

  x -- x is a x[3] -- 3-element array of (x[3])() -- function returning *(x[3])() -- pointer to (*(x[3])())[5] -- 5 element array of *(*(x[3])())[5] -- pointer to int *(*(x[3])())[5]; -- int 

Как написано, это заявление недействительно; вы не можете иметь массив типа функции. Я предполагаю, что это должно было быть чем-то вроде

 int *(*(*x[3])())[5]; 

где x – массив указателей на функции, возвращающие указатели на массивы указателей на int.

Использовать cdecl :

 $ cdecl cdecl> explain int *(*(x[3])())[5] declare x as array 3 of function returning pointer to array 5 of pointer to int 

Это то, что написал cdecl выше.

Когда вы не можете получить доступ к инструменту для перевода декларации для вас, вы можете запомнить эти три правила правил

  1. Существует три основных атома (исключая имена типов)

    Atom [n] преобразуется в Array (с n элементами) .
    Atom () преобразуется в функцию (ы), возвращающуюся .
    Atom * переводит на Pointer (s) в .

  2. Начните с идентификатора, двигающегося вправо , всякий раз, когда вы сталкиваетесь с атомом, переведите его.

  3. Закрытая обрамленная скобка 1 или конец строки реверсируют направление parsingа.

1 Это означает ) при движении вправо ( при перемещении влево.


Ниже представлен суперандантичный перевод int *(*(x[3])())[5] .

  • Начните с идентификатора, x .
    Перевод: x
    Анализ: int *(*(-[3])())[5]
    Направление: Верно.

  • Найдено атом, [3] .
    Перевод: x – массив (с 3 элементами)
    Анализ: int *(*(---)())[5]
    Направление: Верно.

  • Найдено ) , обратное направление.
    Перевод: x – массив (с 3 элементами)
    Анализ: int *(*(----())[5]
    Направление: Слева .

  • Найдено ( , обратное направление.
    Перевод: x – массив (с 3 элементами)
    Анализ: int *(*-----())[5]
    Направление: Верно .

  • Найдено атом () .
    Перевод: x – массив (с 3 элементами) возвращаемых функций
    Анализ: int *(*-------)[5]
    Направление: Верно.

  • Найдено ) , обратное направление.
    Перевод: x – массив (с 3 элементами) возвращаемых функций
    Анализ: int *(*--------[5]
    Направление: Слева .

  • Найдено atom * Перевод: x – это массив (с 3 элементами) функций, возвращающий указатель на
    Анализ: int *(---------[5]
    Направление: Слева.

  • Найдено ( , обратное направление Перевод: x – массив (с 3 элементами) функций, возвращающий указатель на
    Анализ: int *----------[5]
    Направление: Верно .

  • Найдено атом [5] Перевод: x – это массив (с 3 элементами) функций, возвращающих указатель ** в массив (с 5 элементами) **
    Анализ: int *------------
    Направление: Верно.

  • Конец линии, обратное направление. Перевод: * x – массив (с 3 элементами) функций, возвращающий указатель на массив (с 5 элементами) *
    Анализ: int *------------
    Направление: Слева .

  • Найдено атом * . Перевод: * x – массив (с 3 элементами) функций, возвращающий указатель на массив (с 5 элементами) * указателей на
    Анализ: int -------------
    Направление: Слева.

  • Найдено имя типа int . Перевод: x – это массив (с 3 элементами) функций, возвращающих указатель на массив (с 5 элементами) указателей на ints
    Разбор: -----------------
    Направление: Слева.

Перевод: x – это массив (с 3 элементами) функций, возвращающих указатель на массив (с 5 элементами) указателей на int .


Вы также можете поэкспериментировать с удалением скобок:

int **(x[3]())[5] перевод на x – это массив (с 3 элементами) функций, возвращающих массив (с 5 элементами) указателей на указатели на int .

int **x[3]()[5] перевести на x – это массив (с 3 элементами) функций, возвращающих массив (с 5 элементами) указателей на указатели на int .
То же, что и выше!

Конечно, это довольно склонно к ошибкам, я всегда с удовольствием писал этот ответ!