Я все еще использую Венгерскую запись когда дело доходит до элементов UI, где несколько элементов UI связаны с конкретным объектом/значением, например,
lblFirstName для объекта маркировки, txtFirstName для текстового поля. Я определенно не могу назвать их обоих "FirstName", даже если , что беспокойство/ответственность обоих объектов.
, Как другие приближаются к именованию элементы UI?
Это не оператор, это объявление.
Он объявляет 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
Да:
$ cdecl explain void (* x)(int (*[])()); declare x as pointer to function (array of pointer to function returning int) returning void
void (* func) (blah);
- указатель на функцию, принимающую blah
в качестве аргумента , где blah
- это int (* []) ()
- массив указателей на функции.
Вот руководство по чтению объявлений C:
http://www.ericgiguere.com/articles/reading-c-declarations.html
Общая процедура чтения сложных деклараторов состоит в том, чтобы найти крайний левый идентификатор и продолжить работу, помня, что []
и ()
связываются перед *
(т.е. * 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); */
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(*[])());
Удачи!