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

это правильно?

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

R

6 ответов


правое-левое правило легко.

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

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

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

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

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

перейти поставить скобки, идти направо и нажмите [] ---------- в массиве

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


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

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

указатель int:

int *A;

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

int *fn();

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

int *(*pfn)();

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

массив int:

int A[];

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

int (*p)[];

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

int (*fn())[];

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

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

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


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

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

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

IntArrayPtr_t GetColumnSums(void)
{ .... }

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


если вы чувствуете, как обман:

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

int i = function;

компиляция, что на GCC дает:invalid conversion from 'int (*(*)())[5]' to '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]]

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


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

int** (*func)();

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


используя 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 подхода для решения проблемы.