Как вы расшифровываете сложные объявления указателей + массивов? - PullRequest
3 голосов
/ 01 октября 2009

Хотя я использую std::vector почти все время, мне интересно как можно больше узнать об указателях. Примеры того, о чем я говорю:

char* array[5]; // What does it mean?
// 1) pointer to an array of 5 elements!
// 2) an array of 5 pointers?

Меня интересует точное определение этой декларации.

Ответы [ 7 ]

3 голосов
/ 01 октября 2009

cdecl - программа, которая хороша для такого рода вещей. (особенно когда вы добавляете в микс указатели функций!)

Type `help' or `?' for help
cdecl> explain char* foo[5]
declare foo as array 5 of pointer to char
cdecl> declare bar as array 5 of pointer to function (integer, integer) returning char
char (*bar[5])(int , int )
3 голосов
/ 01 октября 2009

Не только указатели и массивы: Как интерпретировать сложные объявления C / C ++ :

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

Одно небольшое изменение справа налево правило: когда вы начинаете читать декларация впервые, вы начинать с идентификатора, и не самые внутренние скобки.

Ваш пример:

char* array[5];

Массив из 5 указателей на символ.

2 голосов
/ 16 декабря 2009

Общая процедура чтения типа в C / C ++:

  1. Определите конечный тип, который может быть базовым типом или идентификатором typedef, и который может иметь модификаторы типа, такие как const, volatile и т. Д. В вашем примере это "char".
  2. Применить операторы к идентификатору в том же порядке приоритета, что и в выражениях. Эти операторы могут быть * (разыменование), [] (индекс) и () (вызывать функцию).

В оригинальной философии синтаксиса ваш пример был бы написан "char * array [5]", идентификатор - "array", а операторы - [] (index), а затем * (разыменование).

Объявление затем читается как контракт: «Если вы примените эти операторы в таком порядке, тогда вы получите объект окончательного типа».

В вашем случае полное предложение звучит так: «если вы индексируете переменную« массив », а затем разыменовываете полученное выражение, вы получаете символ».

Вы также можете считать это так: «если вы индексируете переменную« массив », то вы получаете объект такой, что если вы разыменуете его, вы получите символ»

Хитрость заключается в том, чтобы отслеживать тот факт, что [] и () имеют более высокий приоритет, чем *. Вы можете контролировать порядок операторов с помощью скобок, как и для регулярных выражений.

2 голосов
/ 01 октября 2009

Я узнал правило по часовой стрелке / по спирали очень давно из одной статьи в журнале. Вот онлайн статья, которая описывает технику:

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

1 голос
/ 03 октября 2009

Вы всегда читаете указатели справа налево, интерпретируя '*' как указатель. например char ** a [5] - это массив из 5 указателей на указатели символов ...

1 голос
/ 03 октября 2009

[] имеет более высокий приоритет, чем *, поэтому это массив указателей, а не наоборот.

1 голос
/ 01 октября 2009

char * - это тип, и у вас есть массив из 5 из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...