2013-06-10 3 views
7
int (*ptr)(char (*ch)[]); 

Что означает вышеуказанное обозначение? Означает ли этоПризнание признака указателя функции

ptr является указателем на функцию, которая принимает аргумент, который представляет собой массив указателей на символы, возвращающие целое число?

Как оценить?

+5

Это одна область С, что дизайнеры получили очень плохо неправильно! –

+0

Правда! Трудно оценить такие выражения. – RDX

+2

Это синтаксическая ошибка. –

ответ

3

Там это правило: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

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

Другими словами, существует порядок приоритета (который может быть изменен с помощью скобок), от высшего к низшему:

1) () - функция и [] - массива, слева направо;

2) * - указатель, тип, модификатор типа, справа налево.


Ваш пример

int (*ptr)(char (*ch)[]) 

Мы начинаем с идентификатором

int (*ptr)(char (*ch)[]); // (1)ptr 
     |_|      
     1 

Идентификатор ptr в скобках, поэтому мы разбираем все в parenteses первых

(*ptr) // (1)ptr 
    |_|  
    1 

Там нет ничего вправо, так что мы разбираем к левому

(*ptr) // (1)ptr is (2)a pointer 
||_|  
2 1 

Мы закончили в скобках, теперь мы разбираем справа скобки

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function 
    ||_| |____________| 
    2 1  3 

До сих пор мы игнорируем аргументы функции и разобрать слева от скобок

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function which returns (4)int 
|_| ||_| |____________| 
4 2 1  3 

Таким же образом разбираемого аргумент функции (я вставил некоторые пробелы для лучшего выравнивания)

char (* ch)[ ] // (1)ch is (2)a pointer to (3)array of (4)chars 
|___| | |_| |_| 
    4 2 1 3 

Наконец, мы имеем:

PTR является указателем на функцию, которая возвращает Int и принимает указатель на массив символов в качестве аргумента

1

Он отлично работает в GCC.

Да ptr - указатель на функцию. Это указатель на функцию, возвращающую целое число и принимающий указатель на массив символов в качестве аргумента.

Рассмотрит функцию удовольствие следующего прототипа,

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

fun() является функцией, принимающей указатель на массив символов, в качестве аргумента.

и следующий фрагмент кода компиляции без каких-либо ошибок или предупреждений,

int (*ptr)(char (*ch)[]); 
ptr=fun; 
+0

Вопрос помечен C++. G ++ не удается скомпилировать этот код. Смотрите: http://ideone.com/G7kJpr – jxh

4

PTR является указателем на функцию, которая принимает аргумент, который является указателем на массив символов, возвращающей целое.

+1

как вы оцениваете то же самое? – RDX

+0

Не уверен, что вы просите. Можете ли вы сформулировать это по-другому? – Ziffusion

+0

Я имею в виду, как вы пришли к такому выводу? – RDX

2

Как вы написали, ptr указатель к функции, которая возвращает int и принимает в качестве аргумента указатель на массив из char.

Однако вам не разрешено указывать указатель на массив без привязки к массиву. Таким образом, ваша переменная неправильно указана и не будет компилироваться. Кажется, вы хотите, чтобы ptr имел тип, который может принимать указатель на функцию, которая может принимать любой массив размеров. Для этого требуется построение шаблона. Для аргумента функции, она будет иметь вид:

template <unsigned N> 
int foo (int (*ptr)(char (*)[N])) { 
    //... 
} 

Обычно способом упростить такие типы, чтобы использовать typedef для представления сложных деталей, так что сам переменный становится простым указатель на некоторый тип. Это особенно полезно при попытке написать функцию, которая возвращает указатель на функцию.

void x (char *s) {} 
typedef void xtype (char *); 

void (* y_hard())(char *) { return x; } 
xtype * y_easy() { return x; } 

Однако параметризованный характер аргумента функции затрудняет достижение. Предполагая, что C++ 11, вы можете использовать следующую конструкцию (thanks to this answer):

template <unsigned N> 
using ArrayArg = const char [N]; 

template <unsigned N> 
using Function = int (ArrayArg<N> *); 

template <unsigned N> 
int foo (Function<N> *ptr) { 
    //... 
} 
Смежные вопросы