psilogic: (Default)
[personal profile] psilogic
Мне тут процитировали классическую задачку для кондовых сишников: написать объявление переменной, которая является "указателем на функцию, на указатель на..." - ну и далее какие-нибудь такие навороты. Знакомо?

Так вот, ежели этот блог читают студенты, которых мучают такими задачками, а также старички, которые решают такие задачки методом тыка, то открою страшную тайну: задачки такие решаются чисто механически. Схема такая:

1. Пишем какой-нибудь идентификатор
2. Далее в цикле:

- прочитав "указатель на..."
- ставим * слева

- прочитав "ссылка на..."
- ставим & слева

- прочитав "массив из..."
- ставим [] справа. если будет сказано количество элементов, пишем, в [] сколько их

- прочитав "... функция..."
- просто ставим () справа

- прочитав "...принимающая/принимающую..."
- готовимся писать в тех скобках, что поставили, услышав про функцию

- прочитав "...возвращающая/возвращающую..."
- готовимся писать слева

- прочитав название типа
- ставим его слева

3. В процессе на каждом шаге делаем такую проверку: если использовано слово "указатель/ссылка", а потом используется "массив" или "функция", то перед очередным шагом все заключаем в скобки. Например:

"указатель на массив..." (*x)[]
"указатель на функцию..." (*f)()
но:
"массив указателей..." *x[]
"функция, возвращающая указатель" *f()

- это связано с тем, что приоритет операций & и * ниже, чем [] и ()

4. добавляем ;


В большинстве случаев эта тупая метода прокатывает с первого раза. Если нет, разбиваем на части и используем typedef-ы.

Пример:

"Указатель на указатель на массив из двух указателей на указатель на int"

x
"Указатель на"
*x
"указатель на"
**x
" массив из" (правило 3!)
(**x)[]
"двух "
(**x)[2]
"указателей на"
*(**x)[2]
" указатель на"
**(**x)[2]
"int"
int **(**x)[2];

Date: 2010-03-04 02:40 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
Афигеть какая страшная тайна. Прямо откровение какое-то, не меньше. В следующем номере читайте сенсацию: схема чисто механического решения для примеров из учебника по математике для третьего класса. Трёхстраничное пособие в помощь гениальным студентам, которых преподы-уроды мордуют неоправданно сложными примерами по арифметике.

Date: 2010-03-04 02:51 pm (UTC)
From: [identity profile] psilogic.livejournal.com
ГГГ

И вы никогда не наблюдали сценку, когда опытный программер решает задачки этого типа методом тыка, не? ;)

Date: 2010-03-04 02:52 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
Не доводилось. :)
Вроде это всё-тки совсем азы.

Date: 2010-03-04 03:00 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Ну вот а мне доводилось. Так что, хоть и не откровение, но пущай лежит - вдруг да пригодицца.

Date: 2010-03-04 03:06 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
Когда возникает такой товраищ на горизонте, который задачи уровня грамматики языка решает методом тыка, его сразу надо посылать читать не такие вот отдельные тексты, а стандарт языка. В данном случае, Керниган-Ричи, второе издание, 1988 год, 272 страниц. Это два вечера вдумчивого чтения. И глупых вопросов больше не будет, вместо них будет нормальное понимание, как устроен язык.

Date: 2010-03-04 03:12 pm (UTC)
From: [identity profile] psilogic.livejournal.com
И при чем тут стандарт изыка? Это конкретная задачка, которая может в простых случаях решаться по аналогии/интуитивно, а в сложных - тыком или механически.

Date: 2010-03-04 03:38 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
При том, что кроме аналогии, интуиции, тыка и механического решения, существует ещё один способ решения задач. Наиболее полезный в реальной жизни: осмысленный. Он становится возможным (а так же самым простым, быстрым и естественным), когда в точности понимаешь, что делаешь. Для этого понимания книжки про стандарт языка бывают очень полезны.

Например если немного понимаешь мысли, стоявшие за Си, никогда не перепутаешь int *f() и int (*f)().
Понимать нужно всего лишь две вещи:
- Операция () как и [] имеет более высокий приоритет, чем *. Проверочная конструкция:
int *f() = int* f().
(Из чего немедленно ясно, что в первом случае у нас функция, возвращающая указатели на целые числа.)

- Принцип подстановки: если а определено как int *a, то должно иметь тип int. Если f определено как int f(), то f() должно иметь тип int. Соответственно *f во втором случае должно иметь тот же тип, что и x в int x(). (Из чего немедленно ясно, что во втором случае у нас указатель на функцию, возвращающую целые числа.)

Date: 2010-03-04 04:02 pm (UTC)
From: [identity profile] psilogic.livejournal.com
И о чем мы спорим? Ты предложил еще один механический способ... imho более медленный.

Date: 2010-03-04 04:15 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
Думать головой и понимать, почему всё устроенно именно так как устроено — это механический способ? :-)

http://www.trizway.com/art/article/210.html (Классическая “Он чинит приёмники, думая” Р. Фейнмана.)

Date: 2010-03-04 06:13 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Ммм... значит я тебя не понял. Представь себе, что "как устроено" уже известно. И надо по-быстрому написать синтаксически грамотную конструкцию. Или наоборот - конструкция есть, надо по-быстрому понять, как это устроено. Ибо растягивать и смаковать процесс перехода от синтаксиса к семантике и обратно нет никакого смысла.

Date: 2010-03-04 06:16 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
> Представь себе, что "как устроено" уже известно.
Как ни странно, не могу себе представить, чтобы я хорошо понимал, «как устроено», и при этом не мог сходу написать синтаксически верную конструкцию такого вот типа. Ну не знаю, может у меня мозги как-то криво работают.

Date: 2010-03-04 06:43 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Может, работают именно так, как описано выше - просто ты делаеьш это на автомате.

Date: 2010-03-04 06:45 pm (UTC)
ext_615659: (Default)
From: [identity profile] akuklev.livejournal.com
Наверное да.

Date: 2010-03-04 02:47 pm (UTC)
From: [identity profile] http://users.livejournal.com/sharper_/
О! Кстати, вспомнил, что тебя можно поднапрячь, ибо алгоритмист. А скажи почто cтруктуры данных не в почёте? Ну, ясно, что ООП превозмогло, но это же совершенно другое, в пределе, представление инфы. Не нуждающееся в данных. Т.е. сама структура, представленная адресами, и есть данные.

Date: 2010-03-04 02:59 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Объект в ООП - это не замена для структур данных, и не замена для алгоритмов. Это объединение того и другого в удобной упаковке по принципу "все, что на одну тему, лежит рядом".

"В перделе" ты, возможно, имеешь в виду то, что есть такие объекты-интерфейсы, которые кагбэ не имеют в себе данных (полей), а только методы (алгоритмы). Так это не так. Обычно в объекте-интерфейсе так или иначе спрятан адрес объекта-реализации, а в нем - все те самые данные. То есть, это чисто оформление такое, защищающее от некоторых проблем (а иногда создающее новые проблемы).

Date: 2010-03-04 03:28 pm (UTC)
From: [identity profile] http://users.livejournal.com/sharper_/
Не... Не в тему. До ООП было структурное программирование. Структвра служила для организации данных. Она и посейчас этому предназначена. Но было ответвление - способпрограммирования, где структуры ибыли самипо себе данными. СТруктуры,заданные адресами, данных не содержали, а представляли сосбой множества. Вот что с ними стало?

Date: 2010-03-04 03:38 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Слово "структура" может подразумевать две вещи. Во-первых, собственно организованный набор данных. Во-вторых, схему организации. Схема организации описывает, какие именно данные должны лежать, сколько занимать и (да) какие адреса они имеют относительно друг друга и начала набора данных. Ты о втором говоришь?

Первое - это "значение" или "экземпляр", второе - тип значения, оба они обзываются словом "структура".

Date: 2010-03-04 03:47 pm (UTC)
From: [identity profile] http://users.livejournal.com/sharper_/
Тыменя совершенно не понимаешь! Нет данных в структуре, есть только структура - связанный адресами список и ВСЁ! Никаких данных внутри! Узел списка и есть данные! Куда делся способ? Где надыбать? Первичная классификация разрулиалась на списковом представлении множемств. Начало 70-х.
--------------------
Кстати, возник личнный вопрос. Кинь мне на почту, чтобы ответить. Твою не нашёл.

Date: 2010-03-04 04:00 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Ты часом не про LISP и лямбда-исчисление?
--------
xoxox(САБАКА)list.ru

Date: 2010-03-04 04:15 pm (UTC)
From: [identity profile] http://users.livejournal.com/sharper_/
LISP очень рядом, но был то ли диалект, то ли теория,что типа данных структурам вообщее не требуется.

Date: 2010-03-04 02:51 pm (UTC)
From: [identity profile] pascendi.livejournal.com
А потом надо подробно объяснить человеку, почему НЕ НАДО пользоваться такими штучками в реальной жизни :-)

Date: 2010-03-04 03:02 pm (UTC)
From: [identity profile] psilogic.livejournal.com
В реальной жизни обычно вопрос пользоваться/не пользоваться не стоит: "штучка" откуда-то уже взялась и надо с ней работать.

Date: 2010-03-04 06:12 pm (UTC)
From: [identity profile] piter239.livejournal.com
метапрограмма, однако!

Обожаю такие штуки

Date: 2010-03-08 02:45 am (UTC)
From: [identity profile] boldcat.livejournal.com
Ну так в учебнике Кернигана-Ричи есть программа, которая делает это же.

Date: 2010-03-14 05:57 pm (UTC)
From: [identity profile] gaussrifle.livejournal.com
это все хорошо прокатывает, пока нет дела до указателя на функцию член класса

ведь там приходится обязательно писать имя класса и значек ::*

но зато за счет этого можно легко организовать замену майкрософтских propetries для членов класса стандартными средствами С++, даже не boost и не tr1
Page generated Sep. 3rd, 2025 08:09 pm
Powered by Dreamwidth Studios