C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  Update World C++: Сборник GPL QT исходников
  Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Нетология

 Правило право-лево разбора сложных конструкций / Сложные конструкции / Стандарты программирования

Правило "право-лево"

Автор

Этот текст не мой. Авторство принадлежит Alexander V. Naumochkin (к сожалению, знаю только адрес в сети FIDO, 2:5020/59), на мой взгляд, один из самых грамотных C++ программистов, которых я когда-нибудь (лично или "виртуально") встречал. Тем не менее, считаю просто-таки своим долгом выложить этот текст здесь, потому что он отличается очень большой полезностью, а в FAQ конференции SU.C_CPP до сих пор не включен. Кроме того, я его больше нигде и не встречал, так что пусть здесь полежит. Надеюсь, Александр не обидится.


А как вообще фоpмулиpуется основной пpинцип pазбоpа сложных синтаксических констpукций языка, навpоде "указатель на функцию, возвpащающую указатель на массив из тpёх указателей на функции, возвpащающие значение int"?


Давно и чётко формализовано в виде правила "право-лево". Всё предельно просто. Имеем:


() - функция, возвращающая...

[] - массив из...

* - указатель на...


Процесс разбора итеративный:


Первым делом находим имя, от которого и будем плясать. Пляски начинаются со слов "Имя есть..."

Следующий шаг - шаг вправо. Что там у нас справа? Если (), то говорим, что "Имя есть функция, возвращающая...". (если промеж скобок что-то есть, то "Имя есть функция, принимающая то, что между скобок, и возвращающая...") Если там [], то "Имя есть массив из..." И таким вот образом мы идём вправо до тех пор, пока не дойдём до конца объявления или правой ) скобки. Тут тормозим...

...и начинаем танцевать влево. Что у нас слева? Если это что-то не из приведённой выше таблицы (то есть не (), [], *), то просто добавляем к уже имеющейся расшифровке. Если же там что-то из этих трёх символов, то добавляем то, что написано в таблице. И так танцуем до тех пор, пока не дотанцуем до конца (точнее - начала объявления) или левой ( скобки. Если дошли до начала, то всё готово. А если дошли до (, то по уже означенной итеративности переходим к шагу 2 - пляски вправо продолжаем.


Пример:


int (*(*(*fptr)())[3])();

^^^^

Hаходим имя и записываем "fptr есть..."

Шаг вправо, но там ), потому идём влево

int (*(*(*fun)())[3])();

^

и получаем "fptr есть указатель на..."

Продолжаем ехать влево, но тут (. Идём вправо

int (*(*(*fun)())[3])();

^^

получаем "fptr есть указатель на функцию, возвращающую..." Снова ), опять влево.

Получаем

int (*(*(*fun)())[3])();

^

"fptr есть указатель на функцию, возвращающую указатель на..." Слева опять (, идём вправо.

Получаем

int (*(*(*fun)())[3])();

^^^

"fptr есть указатель на функцию, возвращающую указатель на массив из трёх..." И снова справа ), отправляемся влево

Получаем

int (*(*(*fun)())[3])();

^

"fptr есть указатель на функцию, возвращающую указатель на массив из трёх указателей на..." Снова разворот вправо по причине (

Получаем

int (*(*(*fun)())[3])();

^^

"fptr есть указатель на функцию, возвращающую указатель на массив из трёх указателей на функции, возвращающие..." Тут конец описания, поехали влево и получили окончательную расшифровку этой каракули

int (*(*(*fun)())[3])();

^^^

"fptr есть указатель на функцию, возвращающую указатель на массив из трёх указателей на функции, возвращающие int"

Именно то, чего ты и хотел. Просто?


© 2000-2002, Andrey L. Kalinin mailto:andrey@kalinin.ru




Letyshops [lifetime]