Как вы читаете объявления C?

Хотя стандарт C ++ не имеет такого требования, некоторым компиляторам требуется, чтобы все шаблоны функций и классов были доступны в каждой используемой системе переводов. Фактически для этих компиляторов тела шаблонных функций должны быть доступны в файле заголовка. Повторить: это означает, что эти компиляторы не позволят их определять в файлах без заголовка, таких как .cpp-файлы

Существует ключевое слово export , которое должно смягчать этот проблема, но он нигде не близок к тому, чтобы быть портативным.

41
задан Lazer 26 September 2010 в 18:36
поделиться

9 ответов

Я обычно использую то, что иногда называют, 'правая рука по часовой стрелке управляют'. Это идет как это:

  • Начинают с идентификатора.
  • Переходят к непосредственному праву на него.
  • Тогда двигаются по часовой стрелке и прибывают в левую сторону.
  • Двигаются по часовой стрелке и прибывают в правую сторону.
  • Делают это, пока объявление не было проанализировано полностью.

существует дополнительное метаправило, которое должно заботиться о:

  • , Если существуют круглые скобки, завершите каждый уровень круглых скобок перед выездом.

Здесь, 'идя' и 'перемещаясь' куда-нибудь означает читать символ там. Правила для этого:

  • * - указатель на [1 117]
  • () - функция, возвращаясь
  • (int, int) - функция, берущая два ints и возвращающаяся
  • int, char, и т.д. - int, char, и т.д.
  • [] - массив [1 121]
  • [10] - массив десять
  • и т.д.

Так, например, int* (*xyz[10])(int*, char) читается как:

xyz

массив десять

указатель на [1 130]

функция, берущая интервал* и символ и возвращающаяся

интервал*

22
ответ дан kiritsuku 26 September 2010 в 18:36
поделиться

Автоматическое решение является cdecl.

В целом, Вы объявляете переменную путем, Вы используете ее. Например, Вы разыменовываете указатель p как в:

char c = * p

Вы объявляете его подобно выглядящим способом:

char * p;

То же идет для волосатых указателей функции. Давайте объявим, что f старый добрый "указатель на указатель возврата функции на интервал" и внешнее объявление только, чтобы быть забавным. Это - указатель на функцию, таким образом, мы запускаем с:

extern * f();

Это возвращает указатель на интервал, так где-нибудь впереди там существует

extern int * * f(); // XXX not quite yet

Теперь, который является корректной ассоциативностью? Я никогда не могу помнить, так используйте некоторую круглую скобку.

extern (int *)(* f)();

Объявляют его способ, которым Вы используете его.

0
ответ дан jfm3 26 September 2010 в 18:36
поделиться

cdecl предлагает интерфейс командной строки так, давайте дадим ему попытку:

cdecl> explain int ***c[][]
declare c as array of array of pointer to pointer to pointer to int

другой пример

explain int (*IMP)(ID,SEL) 
declare IMP as pointer to function (ID, SEL) returning int

Однако существует целая глава об этом в книге "C Непостижимые тайны", названный "Восстанавливание объявлений в C.

1
ответ дан Antti Haapala 26 September 2010 в 18:36
поделиться

Cdecl (и C++ decl) является программой для кодирования и декодирования C (или C++) описания типа.

http://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html

4
ответ дан Jorge Ferreira 26 September 2010 в 18:36
поделиться

Назад, когда я делал C, я использовал программу, названную "cdecl". Кажется, что это находится в Ubuntu Linux в cutils или cdecl пакете, и это, вероятно, доступно в другом месте.

3
ответ дан Paul Tomblin 26 September 2010 в 18:36
поделиться

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

В любом случае, каждый раз, когда Вы действительно понимаете объявления, возможно, можно выяснить способ упростить их для создания их более читаемыми для следующего парня.

0
ответ дан Doug T. 26 September 2010 в 18:36
поделиться

Одно слово: cdecl

Damnit, разбитый на 15 секунд!

6
ответ дан Mateusz Piotrowski 26 September 2010 в 18:36
поделиться

Эта статья объясняет относительно простые 7 правила, которые позволят Вам считать любое объявление C, если Вы будете желать или должными быть сделать так вручную: http://www.ericgiguere.com/articles/reading-c-declarations.html

  1. Находит идентификатор. Это - Ваша начальная точка. На листке бумаги запишите, "объявляют идентификатор как".
  2. Взгляд направо. Если нет ничего там, или существует правая круглая скобка")", goto шаг 4.
  3. Вы теперь расположены или на массив (левая скобка) или на функцию (левая круглая скобка) дескриптор. Может быть последовательность их, закончившись или с несопоставленной правой круглой скобкой или с концом оператора объявления (точка с запятой или "=" для инициализации). Для каждого такого дескриптора, читая слева направо:

    • , если пустой массив" []", запишите "массив"
    • , если массив с размером, запишите "размер массива"
    • , если функция" ()", запишите "функцию, возвратившись"

    Остановка в несопоставленной круглой скобке или конце оператора объявления, какой бы ни на первом месте.

  4. Возврат к стартовой позиции и взгляду налево. Если нет ничего там, или существует левая круглая скобка" (", goto шаг 6.
  5. Вы теперь расположены на дескриптор указателя, "* ". Может быть последовательность их налево, закончившись или с несопоставленной левой круглой скобкой" (" или запуск оператора объявления. Чтение справа налево, для каждого дескриптора указателя пишет "указатель на". Остановитесь в несопоставленной круглой скобке или запуске оператора объявления, какой бы ни является первым.
  6. В этой точке у Вас есть или заключенное в скобки выражение или полный оператор объявления. Если Вы имеете заключенное в скобки выражение, рассматриваете его как Вашу новую начальную точку и возвращаетесь к шагу 2.
  7. , Записывают спецификатор типа. Остановиться.

, Если Вы соглашаетесь с инструментом, тогда я вторые предложение для использования программы cdecl: http://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html

32
ответ дан Colonel Thirty Two 26 September 2010 в 18:36
поделиться

Только что наткнулся на поясняющий раздел в « Развитие языка C »:

Для каждого объекта такого составного типа уже существовал способ упомяните базовый объект: проиндексируйте массив, вызовите функцию, используйте оператор косвенного обращения к указателю. Аналогичные рассуждения привели к синтаксису объявления для имен, отражающему синтаксис выражения, в котором обычно встречаются имена. Таким образом,

int i, * pi, ** ppi;

объявляют целое число, указатель на целое число, указатель на указатель на целое число. Синтаксис этих объявлений отражает наблюдение, что все i, * pi и ** ppi дают тип int при использовании в выражении. Точно так же

int f (), * f (), (* f) ();

объявляют функцию, возвращающую целое число, функцию, возвращающую указатель на целое число, указатель на функцию, возвращающую целое число;

int * api [10], (* pai) [10];

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

0
ответ дан 26 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: