Entry tags:
Страшная тайна ;)
Мне тут процитировали классическую задачку для кондовых сишников: написать объявление переменной, которая является "указателем на функцию, на указатель на..." - ну и далее какие-нибудь такие навороты. Знакомо?
Так вот, ежели этот блог читают студенты, которых мучают такими задачками,а также старички, которые решают такие задачки методом тыка, то открою страшную тайну: задачки такие решаются чисто механически. Схема такая:
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];
Так вот, ежели этот блог читают студенты, которых мучают такими задачками,
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];
no subject
no subject
no subject
И вы никогда не наблюдали сценку, когда опытный программер решает задачки этого типа методом тыка, не? ;)
no subject
no subject
Вроде это всё-тки совсем азы.
no subject
"В перделе" ты, возможно, имеешь в виду то, что есть такие объекты-интерфейсы, которые кагбэ не имеют в себе данных (полей), а только методы (алгоритмы). Так это не так. Обычно в объекте-интерфейсе так или иначе спрятан адрес объекта-реализации, а в нем - все те самые данные. То есть, это чисто оформление такое, защищающее от некоторых проблем (а иногда создающее новые проблемы).
no subject
no subject
no subject
no subject
no subject
no subject
Первое - это "значение" или "экземпляр", второе - тип значения, оба они обзываются словом "структура".
no subject
Например если немного понимаешь мысли, стоявшие за Си, никогда не перепутаешь int *f() и int (*f)().
Понимать нужно всего лишь две вещи:
- Операция () как и [] имеет более высокий приоритет, чем *. Проверочная конструкция:
int *f() = int* f().
(Из чего немедленно ясно, что в первом случае у нас функция, возвращающая указатели на целые числа.)
- Принцип подстановки: если а определено как int *a, то *а должно иметь тип int. Если f определено как int f(), то f() должно иметь тип int. Соответственно *f во втором случае должно иметь тот же тип, что и x в int x(). (Из чего немедленно ясно, что во втором случае у нас указатель на функцию, возвращающую целые числа.)
no subject
--------------------
Кстати, возник личнный вопрос. Кинь мне на почту, чтобы ответить. Твою не нашёл.
no subject
--------
xoxox(САБАКА)list.ru
no subject
no subject
no subject
http://www.trizway.com/art/article/210.html (Классическая “Он чинит приёмники, думая” Р. Фейнмана.)
no subject
no subject
Обожаю такие штуки
no subject
no subject
Как ни странно, не могу себе представить, чтобы я хорошо понимал, «как устроено», и при этом не мог сходу написать синтаксически верную конструкцию такого вот типа. Ну не знаю, может у меня мозги как-то криво работают.
no subject
no subject
no subject
no subject
ведь там приходится обязательно писать имя класса и значек ::*
но зато за счет этого можно легко организовать замену майкрософтских propetries для членов класса стандартными средствами С++, даже не boost и не tr1