Как Вы объявляете указатель на функцию, которая возвращает указатель на массив международных значений в C / C++?

Это корректно?

int (*(*ptr)())[];

Я знаю, что это тривиально, но я смотрел на старый тест о подобных конструкциях, и эта конкретная комбинация не была на тесте, и это действительно сводит меня с ума; я просто должен удостовериться. Существует ли четкое и основательное понятное правило к подобным объявлениям? (т.е.: указатель на... массив.. указатели на... функции, что.... и т.д. и т.д.) Спасибо!

R

9
задан Prasoon Saurav 5 August 2010 в 03:09
поделиться

6 ответов

Правило право-лево упрощает задачу.

int (* (* ptr) ()) []; можно интерпретировать как

Начать с имени переменной ------------------- ------------ ptr

Право только ) , так что идите налево, чтобы найти * -------- ------ - указатель

Выйдите из скобок и встретите () ----------- на функцию, которая не принимает аргументов (в случае, если число аргументов C не указано)

Идите налево, найдите * -------------------------- ---------------------- и возвращает указатель

Перейти в круглые скобки, перейти вправо и нажать [] ------ ---- в массив

Снова идите налево, найдите int ------------------------ ------------- ints .

14
ответ дан 4 December 2019 в 09:11
поделиться

Практически во всех ситуациях, когда вы хотите вернуть указатель на массив, самое простое, что нужно сделать, - это вернуть указатель на первый элемент массива. Этот указатель может использоваться в тех же контекстах, что и имя массива, и не обеспечивает более или менее косвенного обращения, чем возврат указателя типа «указатель на массив», действительно, он будет содержать то же значение указателя.

Если вы последуете этому, вам нужен указатель на функцию, возвращающую указатель на int . Вы можете создать это (построение объявлений проще, чем синтаксический анализ).

Указатель на int :

int *A;

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

int *fn();

указатель на функцию, возвращающую указатель на int :

int *(*pfn)();

Если вы действительно хотите вернуть указатель на функцию, возвращающую указатель на массив int , вы можете выполнить тот же процесс.

Массив int:

int A[];

Указатель на массив int:

int (*p)[];

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

int (*fn())[];

Указатель на fn ...:

int (*(*pfn)())[];

это то, что у вас есть.

6
ответ дан 4 December 2019 в 09:11
поделиться

Не знаете. Просто разделите его на два typedef: одно для указателя на массив int, а другое для указателя на функции. Что-то вроде:

typedef int (*IntArrayPtr_t)[];
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void);

Это не только более читабельно, но и упрощает объявление / определение функций, которые вы собираетесь назначить переменной:

IntArrayPtr_t GetColumnSums(void)
{ .... }

Конечно, это предполагает, что это была реальная ситуация, а не вопрос на собеседовании или домашнее задание. Я все равно считаю, что это лучшее решение для таких случаев, но это только я. :)

2
ответ дан 4 December 2019 в 09:11
поделиться

Вот мое решение ...

int** (*func)();

Функтор возвращает массив int *. Это не так сложно, как ваше решение.

0
ответ дан 4 December 2019 в 09:11
поделиться

Если вам хочется обмануть:

typedef int(*PtrToArray)[5];
PtrToArray function();

int i = function;

Компиляция этого в gcc дает: недопустимое преобразование из int (* (*) ()) [5] в int . Первый бит - это тип, который вы ищете.

Конечно, когда у вас есть PtrToArray typedef, все упражнение становится более тривиальным, но иногда это бывает полезно, если у вас уже есть имя функции, и вам просто нужно его где-то закрепить. И по какой-то причине вы не можете полагаться на хитрость шаблонов, чтобы скрыть от вас кровавые подробности.

Если ваш компилятор поддерживает это, вы также можете сделать это:

typedef int(*PtrToArray)[5];
PtrToArray function();

template<typename T> void print(T) {
    cout << __PRETTY_FUNCTION__ << endl;
}

print(function);

Что на моем компьютере производит void function (T) [with T = int (* (*) ()) [5] ]

Умение читать типы довольно полезно, поскольку понимание ошибок компилятора часто зависит от вашей способности понять, что означают все эти круглые скобки. Но делать их самому менее полезно, ИМО.

1
ответ дан 4 December 2019 в 09:11
поделиться

Используя cdecl, вы получите следующее

cdecl> declare a as pointer to function returning pointer to  array of int;
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension'
    (maybe you mean "pointer to object")
int (*(*a)())[]

Этот вопрос из C-faq похож, но предлагает 3 подхода к решению проблемы.

0
ответ дан 4 December 2019 в 09:11
поделиться