Можно ли объяснить следующий оператор C/C++?

Я все еще использую Венгерскую запись когда дело доходит до элементов UI, где несколько элементов UI связаны с конкретным объектом/значением, например,

lblFirstName для объекта маркировки, txtFirstName для текстового поля. Я определенно не могу назвать их обоих "FirstName", даже если , что беспокойство/ответственность обоих объектов.

, Как другие приближаются к именованию элементы UI?

10
задан warren 6 November 2009 в 13:09
поделиться

6 ответов

Это не оператор, это объявление.

Он объявляет func как указатель на функцию, возвращающую void и принимающую единственный аргумент типа int (* []) ​​() , который сам по себе является указателем на указатель на функцию, возвращающую int и принимающую фиксированное, но неуказанное количество аргументов.


Вывод cdecl для маловерных:

cdecl> explain void (*f)(int(*[ ])());
declare f as pointer to function (array of pointer to function returning int) returning void
20
ответ дан 3 December 2019 в 13:15
поделиться

Да:

$ cdecl
explain void (* x)(int (*[])());
declare x as pointer to function 
  (array of pointer to function returning int) returning void
5
ответ дан 3 December 2019 в 13:15
поделиться

void (* func) (blah); - указатель на функцию, принимающую blah в качестве аргумента , где blah - это int (* []) ​​() - массив указателей на функции.

2
ответ дан 3 December 2019 в 13:15
поделиться

Вот руководство по чтению объявлений C:

http://www.ericgiguere.com/articles/reading-c-declarations.html

2
ответ дан 3 December 2019 в 13:15
поделиться

Общая процедура чтения сложных деклараторов состоит в том, чтобы найти крайний левый идентификатор и продолжить работу, помня, что [] и () связываются перед * (т.е. * a [] - это массив указателя, а не указатель на массив). Этот случай немного усложняется из-за отсутствия идентификатора в списке параметров, но опять же, [] связывается перед * , поэтому мы знаем, что * [] указывает на массив пойтнеров.

Итак, учитывая

void (*func)(int(*[ ])());

, мы разбиваем его следующим образом:

       func                   -- func
      *func                   -- is a pointer
     (*func)(           )     -- to a function taking
     (*func)(     [ ]   )     --    an array
     (*func)(    *[ ]   )     --    of pointers
     (*func)(   (*[ ])())     --    to functions taking 
                              --      an unspecified number of parameters
     (*func)(int(*[ ])())     --    returning int
void (*func)(int(*[ ])());    -- and returning void

На практике это будет выглядеть примерно так:

/**
 * Define the functions that will be part of the function array
 */
int foo() { int i; ...; return i; }
int bar() { int j; ...; return j; }
int baz() { int k; ...; return k; }
/**
 * Define a function that takes the array of pointers to functions
 */
void blurga(int (*fa[])())
{
  int i;
  int x;
  for (i = 0; fa[i] != NULL; i++)
  {
    x = fa[i](); /* or x = (*fa[i])(); */
    ...
  }
}    
...
/**
 * Declare and initialize an array of pointers to functions returning int
 */
int (*funcArray[])() = {foo, bar, baz, NULL};
/**
 * Declare our function pointer
 */
void (*func)(int(*[ ])());
/**
 * Assign the function pointer
 */
func = blurga;
/**
 * Call the function "blurga" through the function pointer "func"
 */
func(funcArray); /* or (*func)(funcArray); */
31
ответ дан 3 December 2019 в 13:15
поделиться

Geordi - бот C ++, позволяющий обучать:

<litb> geordi: {} void (*func)(int(*[ ])());
<litb> geordi: -r << ETYPE_DESC(func)
<geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function 
         returning an integer and returning nothing

Он может делать много полезных вещей, например, показывать объявления всех параметров (на самом деле это просто сопоставление необработанных имен правил грамматики C ++ ):

<litb> geordi: show parameter-declarations
<geordi> `int(*[ ])()`.

Давайте сделаем это в обратном направлении:

<litb> geordi: {} int func;
<litb> geordi: make func a pointer to function returning void and taking array of pointer to 
       functions returning int
<litb> geordi: show
<geordi> {} void (* func)(int(*[])());

It выполняет все, что вы ему дадите, если вы его попросите. Если вы прошли обучение, но просто забыли некоторые пугающие правила в скобках, вы также можете смешать описания типов в C ++ и стиле geordi:

<litb> geordi: make func a (function returning void and taking (int(*)()) []) *
<geordi> {} void (* func)(int(*[])());

Удачи!

2
ответ дан 3 December 2019 в 13:15
поделиться