int *(*table())[30];
Я не могу найти решение в любом месте. Что такое * table(), может ли это быть функцией или массивом?в C, что означает это объявление: int * (* table()) [30];
Не могли бы вы рассказать мне, что это значит?
int *(*table())[30];
Я не могу найти решение в любом месте. Что такое * table(), может ли это быть функцией или массивом?в C, что означает это объявление: int * (* table()) [30];
Не могли бы вы рассказать мне, что это значит?
Чтение таких конструкций намного проще, если вы замените части декларации, которые могут быть заменены, с заменяющим именем. Скажем, f
- это table()
, что является функцией, принимающей неопределенное количество аргументов, а t
- это тип int*
.
Тогда декларация становится:
t(*f)[30];
, который, очевидно, является указателем на массив из 30 элементов t
.
Заменить f
, и мы получим функцию принимая неопределенное количество аргументов, и возвращает указатель на массив из 30 элементов т:
t(*table())[30];
Заменить t
и мы получим функцию, принимая неопределенное количество аргументов и возвращает указатель на массив из 30 элементов указателя INT:
int*(*table())[30];
Вы можете расшифровать это изнутри:
int *(*table())[30];
Внутреннее связывание - это table()
, что является функцией с неопределенными аргументами. Следующий уровень - *table()
, поэтому table
возвращает указатель на что-то. Следующий уровень - (*table())[30]
, поэтому он возвращает указатель на массив длиной 30 строк. Следующий уровень - *(table())[30]
, поэтому он возвращает указатель на массив указателей длиной 30 строк. На последнем уровне добавляется спецификатор типа, int *(*table())[30]
.
Таким образом, table
является функцией (с неопределенными аргументами), которая возвращает указатель на массив длиной 30 строк указателей на int
.
Проходит ли оно до 30-го места в массиве указателей int или возвращает указатель массива длиной 30? –
@DeBanana Поскольку это декларатор, 30 - длина массива, а не индекс. –
Линия:
int *(*table())[30];
заявляет, что «таблица является функция, возвращающая указатель на массив из 30 указателей на INT»
Есть много хороших статей о том, как читать декларации типа C. Here is one of them.
Резюмируя:
правил:
[]
и ()
и *
. Вызовите этот $ identifier.Ваше заявление будет оформлено как: $identifier
... $typename
.
Начать с "$ identifier is (n)".
Если вы можете пойти направо, воспользовавшись [...]
или (...)
, добавьте это в свою декларацию. [...]
- это (возможно, пустое) объявление массива, написанное «array (of ...)»; а (...)
- это (возможно, пустое) объявление функции, написанное «возврат функции» или «возврат функции (...)».
Если вы не можете идти правильно, потому что вы достигаете точки с запятой или запятой или закрывающей круглой скобкой, то вы должны идти влево. Идите влево, потребляя либо $ typename, если вы находитесь в конце процесса, либо потребляете декларацию указателя (*
, написали «указатели (ов) на») или используете открывающую скобку. После использования любого из них, кроме $ typename, попробуйте снова пойти прямо.
Помните: если хотите, пойдите направо, идите налево, если нужно.
Ваш вопрос, вновь
Имея это в виду, давайте снова посмотрим:
int *(*table())[30];
Шаг за шагом:
Начните с "$ идентификатор (п)": "таблица (п)" ${typename} *(*${declaration}())[30];
Идите направо: "... функция, возвращающая" ${typename} *(* ${declaration})[30];
)
${typename} * ${declaration} [30];
${typename} * ${declaration};
;
${typename} * ${declaration}
${typename} ${declaration}
Пишут, что все в порядке, и вы получите:
таблица (п) функция, возвращающая указатель (ы) в массив 30 указателя (s) в целое
зачистить предложения путем удаления (s), где не требуется, и замена одного указателя с «указателем»:
table - это функция, возвращающая указатель на массив из 30 указателей на int.
Выше декларация может быть понята правилом по часовой стрелке/спирали.
Ниже описывается, как разобрать заявление, используя правило:
1) таблица является функцией с неуказанных аргументов.
2) стол() функция возвращает указатель .
3) указатель возвращенный таблицы() функции указывает на массив элементов.
4) Каждый элемент имеет тип целочисленных указателей т.е. каждый элемент указывает на целое число.
Подробнее о правиле хорошо описано в этой ссылке: The ``Clockwise/Spiral Rule''
Идентификатор таблицы это функция, которая возвращает указатель на массив из 30 целочисленных указателей. В качестве дополнения к изучению так называемого clockwise/spiral rule вы можете использовать сайт, например, http://cdecl.org/.
Если бы мне удалось переписать код, я бы разделил объявление на объявление типа и объявление функции. Таким образом, будет легче понять текст программы. Также я бы назвал результатным типом Таблица и выберем более конкретное имя для функции, которая, скорее всего, вернет специальный вид таблицы, скажем, таблицу Foo. Если это возможно, я бы также избежать пустой список параметров и использовать ключевое слово недействительным указать, что функция не принимает никаких параметров:
typedef int *(*Table)[30];
Table FooTable(void);
[объявить таблицу как функцию, возвращающую указатель на массив 30 указатель на INT] (HTTP: //cdecl.ridiculousfish.com?q=int+*(*table())[30]%3B) – ckruczek
cdecl - ваш друг.'cdecl> explain int * (* table()) [30]' 'объявлять таблицу как функцию, возвращающую указатель на массив 30 указателя на int' – hobbs
Пожалуйста, обратитесь к правилу по спирали/по часовой стрелке http://c-faq.com/ decl/spiral.anderson.html –