LINUX.ORG.RU

[дурацкий вопрос] [C/C++] Как научиться понимать хитрые указатели?


0

1

Преамбуда. Тысячепудовый молот злой Фортуны вновь заставил меня слиться в едином порыве со старым добрым ЦПП.

Так вот, амбула. Там, в ЦПП, всё просто прекрасно, однако, ко стыду своему, я с трудом понимаю тамошние хитрые указатели - особенно, когда намешаны const'ы, массивы и указатели на функции. Где можно прочитать, об этом?


Берн Страуструп «Язык программирования C++», но ещё лучше будет, если перед этим прочесть (и что-то написать для понимания) это:
Б.Керниган, Д.Ритчи «Язык программирования Си» (Глава 5. Указатели и массивы)

blinkenlichten
()

Павловскую почитай, там всё объясняется, правда сопли не разжёваны, но зато сама суть изложена доходчиво.

erfea ★★★★★
()
Ответ на: комментарий от erfea

ошибки синтаксиса в её книгах - вполне обычное явление. В случае в C++ лучше читать Страуструпа.

anonymous
()

2TS:

есть ещё классная штука cdecl, которая умеет вот так:

cdecl> explain void (*f)(int)
declare f as pointer to function (int) returning void

anonymous
()
Ответ на: комментарий от anonymous

Не набивал ничего из её кода, специально в синтаксис тоже не вглядывался, но всё же сомневаюсь что это правда. И собсвенно не в синтаксисе суть, она примеры приводит не синтаксис демонстрировать, а использование той или иной функциональности. Примеры отличные краткие и их не много.

erfea ★★★★★
()

Собственно, я не совсем понял, что имеется ввиду. Могу сделать 2 предположения:

1. Есть трудности с пониманием объявления указателей. Например, непонятно, почему пойнтер на функцию объявляется так:

int (*f)(int);

Насколько мне известно, ни у Стауструпа, ни у Кернигана и Ритчи нет исчерпывающего объяснения деклараций типов. Собственно,если хочется исчерпывающего понимания, то самостоятельный разбор соответствующего куска BNF-спецификации синтаксиса C ничего не заменит. Так что читайте стандарт (да, я понимаю, что приятного в этом мало, но ничего не поделаешь). По поводу общего принципа могу лишь заметить, что если объявлена переменная какого-либо типа (или прототип функции) с именем n, то если n заменить на (*n), то получится переменная, которая содержит пойнтер на этот тип. Точно также есть правила образования массивов, так что изучайте BNF.

2. Есть трудности с пониманием самих указателей. Здесь могу посоветовать только познакомиться с системой команд какого-либо процессора общего назначения (например x86, ARM). Тогда придет понимание того, что пойнтеры — это не более чем целые числа, тип пойнтера нужен для того, чтобы компилятор знал что делать с адресом, если применяется операция разъименования (*), например. Разумеется, детали представления пойнтеров могут отличаться в различных процессорах, но для того чтобы _понять_, почему в C все, что связано с пойнтерами, сделано именно так, а не иначе, знакомство с каким-нибудь конкретным процессором необходимо. Хотя я не исключаю, что есть отдельные личности, для которых достаточно вызубрить стандарт и рассматривать C как абстрактную машину, большинство людей все же лучше осваивает абстракции тогда, когда они проиллюстрированы конкретными примерами.

anonymous
()

Во многих случаях без использования таких указателей можно обойтись.

buddhist ★★★★★
()

«С++ для профессионалов». Еще Андрея Александреску почитай, можно еще Шилдта.

LongLiveUbuntu ★★★★★
()

Франка П. C++: Учебный курс.

anonymous
()

Там, в ЦПП, всё просто прекрасно, однако, ко стыду своему, я с трудом понимаю тамошние хитрые указатели - особенно, когда намешаны const'ы, массивы и указатели на функции.

указатели - это из Си, так что читай K&R

если нужен блиц-курс по С++ почитай «С++ для профессионалов»

shty ★★★★★
()
Ответ на: комментарий от anonymous

> 1. Есть трудности с пониманием объявления указателей. Например, непонятно, почему пойнтер на функцию объявляется так:

int (*f)(int);

Потому что оператор () имеет приоритет перед *. Без скобочек оно будет интерпретироваться как

(int *) f(int), т.е. функция, возвращающая указатель на int

unanimous ★★★★★
()

Как научиться понимать хитрые указатели?

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

*тебе.

knkd
()
Ответ на: комментарий от unanimous

>Потому что оператор () имеет приоритет перед *. Без скобочек оно будет интерпретироваться как

(int *) f(int), т.е. функция, возвращающая указатель на int

Имелось ввиду, что это не мне непонятно, а, возможно, топикстартеру. Несовсем ясно выразился. Ну так я и посоветовал ТС покурить BNF, чтобы стало ясно что над чем имеет приоритет и что означает.

anonymous
()

Ответов по вашему вопросу достаточно, но хочу поправить : нет в русском языке слова амбула, есть слово фабула.

Dikar ★★
()
Ответ на: комментарий от anonymous

А кроме того, ты сказал: «Насколько мне известно, ни у Стауструпа, ни у Кернигана и Ритчи нет исчерпывающего объяснения деклараций типов». Быть может тебе и не известно — это лишь означает, что ты не читал, или невнимательно читал раздел 5.12 «Сложные объявления» второго издание этой книги

anonymous
()
Ответ на: комментарий от anonymous

>А кроме того, ты сказал: «Насколько мне известно, ни у Стауструпа, ни у Кернигана и Ритчи нет исчерпывающего объяснения деклараций типов». Быть может тебе и не известно — это лишь означает, что ты не читал, или невнимательно читал раздел 5.12 «Сложные объявления» второго издание этой книги

Да, был неправ. Там оказывается даже есть спецификация синтаксиса. Видимо дело в том, что очень давно, когда я ее читал, меня эти вещи не сильно интересовали. А потом я стал пользоваться стандартом в качестве справочника.

anonymous
()

Хитрые указатели не нужны. Почитай про typedef и заимей привычку называть типы осмысленно. Пример

typedef int (callback_handle_incoming_data*)(int*);
typedef callback_handle_incoming_data* callback_iterator;
for(callback_iterator i=callback_table;i!=END(callback_table);++i
  sum+=(*i)(mydata);
Так можно наворотить сколь угодно сложную хрень и не запутаться просто добавляя по typedef на каждую единицу смысла.

legolegs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.