Тема: Складні оголошення, правило "право-ліво" [Стаття]
В котрий раз перечитував главу "Складні оголошення" в K&R.. згадав про чудову замітку, яка свого часу спростила мені розуміння цих заплутаних речей. Вирішив її перекласти для нашої спільноти.
А як взагалі формується основний принцип розбіру складних синтаксичних конструкцій мови, типу "вказівник на функцію, що повертає вказівник на масив із трьох вказівників на функції, що повертають int"?
Давно і чітко формалізовано у вигляді правила "право-ліво". Все просто. Маємо:
() - функція, що повертає...
[] - масив із...
* - вказівник на...
Процес розбіру ітеративний:
Першим ділом знаходимо ім'я, від котрого і будем починати. Пляски починаються зі слів "Ім'я є..."
Наступний крок - крок вправо. Що там у нас справа? Якщо (), то говоримо, що "Ім'я є функція, що повертає...". (якщо між дужок щось є, то "Ім'я є функція, приймаюча те, що між дужок, що повертає...")
Якщо там [], то "Ім'я є масив із...". І таким ось чином ми йдемо вправо до тих пір, доки не дійдем до кінця оголошення чи правої ) дужки. Тут пригальмуємо......і починаємо танцювати вліво. Що у нас зліва? Якщо це щось не з наведеної вище таблиці (тобто не (), [], *), то просто додаємо до вже наявної розшифровки. Якщо ж там щось з цих трьох символів, то додаємо те, що написано в таблиці. І так танцюємо до тих пір, доки не дійдемо до кінця (точніше - початку оголошення) або лівої ( дужки. Якщо дійшли до початку, то все готово. А якщо дійшли до (, то по вже зазначеній ітеративності переходимо до кроку 2 - пляски вправо продовжуємо.
Приклад:
int (*(*(*fptr)())[3])(); ^^^^
1. Знаходимо ім'я та записуємо "fptr є..."
2. Крок вправо, але там ), тому ідемо влівоint (*(*(*fptr)())[3])(); ^
і отримуємо "fptr є вказівник на..."
3. Продовжуємо їхати вліво, але тут (. Ідем вправо
int (*(*(*fptr)())[3])(); ^^
отримуємо "fptr є вказівник на функцію, що повертає...". Знову ), знову вліво.
4. Отримуємо
int (*(*(*fptr)())[3])(); ^
"fptr є вказівник на функцію, що повертає вказівник на..." Зліва знову (, ідем вправо.
5. Отримуємо
int (*(*(*fptr)())[3])(); ^^^
"fptr є вказівник на функцію, що повертає вказівник на масив із трьох..." І знову справа ), вирушаємо вліво
6. Отримуємо
int (*(*(*fptr)())[3])(); ^
"fptr є вказівник на функцію, що повертає вказівник на масив із трьох вказівників на..." Знову поворот вправо з причини (
7. Отримуємо
int (*(*(*fptr)())[3])(); ^^
"fptr є вказівник на функцію, що повертає вказівник на масив із трьох вказівників на функції , що повертають..." Тут кінець опису, поїхали вліво та отримали кінцеву розшифровку цієї каракулі
8.
int (*(*(*fptr)())[3])(); ^^^
"fptr є вказівник на функцію, що повертає вказівник на масив із трьох вказівників на функції, що повертають int"
Саме те, чого ти й хотів. Просто?
Першоджерело: http://www.kalinin.ru/programming/cpp/17_07_00.shtml