Недавно мой знакомый из совершенно непрограммистских кругов попросил меня помочь ему с лабораторной работой по C++.
Код был примерно такой:
Этот случай напомнил нам, что тема указателей является, пожалуй, основным источником ошибок у студентов, изучающих язык, и в то же время - своеобразным пропуском, преодоление которого связано со "щелчком" в голове, что, увы, не все учителя умеют вызывать.void do_something(MyObj *input[], int count) { MyObj **copy = new MyObj*[count]; for (int i = 0; i < count; ++i) *copy[i] = *input[i]; .
}
Я надеюсь, что приведенная ниже лингвистическая аналогия поможет нынешним студентам понять эту концепцию и поможет их учителям или друзьям передать им эти знания.
Лет десять назад на одном форуме была детская загадка :
Почему я обедаю? каннибал Пригласили на обед Каннибал?Я хочу показать, что эта загадка самым непосредственным образом связана с C/C++, поскольку тему указателей легко разобрать по аналогии.
Смотреть.
Чтобы понять, что такое «обед каннибала», нам нужно провести лингвистический анализ последнего слова.
Самый простой способ сделать это — прочитать корни справа налево:
- Огр = тот, кто ест людей.
- Каннибал = тот, кто ест каннибалов = тот, кто ест тех, кто ест людей.
- Каннибал = тот, кто ест каннибалов = тот, кто ест тех, кто ест каннибалов = тот, кто ест тех, кто ест тех, кто ест людей.
- MyClass* = указатель на MyClass.
- MyClass** = указатель на MyClass* = указатель на указатель на MyClass.
- MyClass*** = указатель на MyClass** = указатель на указатель на MyClass* = указатель на указатель на указатель на MyClass.
- Обед каннибала = обед того, кто ест каннибалов = каннибал.
- Обед каннибала = еда каннибала = еда того, кто ест каннибалов = каннибал.
То есть лингвистическое правило оказывается таким: помещая слово «еда» или «ужин» слева от слова, оканчивающегося на корень «ед», мы отбрасываем этот последний корень, оставляя перед ним только словарную основу.
.
Но указатели в C/C++ ведут себя аналогично: если слева от сущности типа «указатель на T» или «T*» поставить символ указателя (ту самую звездочку), то в результате мы отбросим один лишний указатель из типа, получив, по сути, T (или, если быть совсем точным, T&, но я намеренно не хочу сейчас затрагивать тему ссылок и прочих lvalue).
Совершенно грубо (игнорируя некоторые правила синтаксиса) можно написать, что
- *(Т*) === Т,
- *(Т**) === Т*,
- **(Т**) === Т,
- *(Т***) === Т**,
- и так далее.
Я просто надеюсь, что эта лингвистическая аналогия поможет некоторым студентам, изучающим C/C++, быстрее понять эту тему.
Если взять звезду в качестве еды, а Люду в качестве базового типа.
Вы поняли.
Теги: #pointers #C++ #C++ #pointer #C++ #C++
-
Пусть Сережа Программирует
19 Oct, 24 -
Скелет В Шкафу, Или Сайт За 200 Долларов
19 Oct, 24