Что такое пойнтер в информатике
Указатели в C++: зачем нужны, когда использовать и чем отличаются от обращения к объекту напрямую
Даже если большинство программистов понимают, в чем разница между объектами и указателями на них, иногда бывает не совсем понятно, в пользу какого из способов обращения к объекту стоит делать выбор. Ниже мы постарались ответить на этот вопрос.
Вопрос
Я заметил, что нередко программисты, чей код я видел, используют указатели на объекты чаще, чем сами эти объекты, т.е., например, используют следующую конструкцию:
Аналогично с методами. Почему вместо этого:
мы должны писать вот это:
Я так понимаю, что это дает выигрыш в скорости, т.к. мы обращаемся напрямую к памяти. Верно? P.S. Я перешел с Java.
Ответ
Заметим, кстати, что в Java указатели не используются в явном виде, т.е. программист не может в коде обратиться к объекту через указатель на него. Однако на деле в Java все типы, кроме базовых, являются ссылочными: обращение к ним происходит по ссылке, хотя явно передать параметр по ссылке нельзя. И еще, на заметку, new в C++ и в Java или C# — абсолютно разные вещи.
Для того, чтобы дать небольшое представление, что же такое указатели в C++, приведем два аналогичных фрагмента кода:
Ближайший эквивалент на C++:
Однако вот это – совершенно другая вещь (C++):
На самом деле, совсем нет. Работа с указателями оформлена в виде кучи, в то время как работа с объектами – это стек, более простая и быстрая структура. Если вы новичок, то у нас для вас есть материал, в котором мы подробно рассказываем, что такое стек и куча.
Строго говоря, этот вопрос объединяет в себе два различных вопроса. Первый: когда стоит использовать динамическое распределение памяти? Второй: когда стоит использовать указатели? Естественно, здесь мы не обойдемся без общих слов о том, что всегда необходимо выбирать наиболее подходящий инструмент для работы. Почти всегда существует реализация лучше, чем с использованием ручного динамического распределения (dynamic allocation) и / или сырых указателей.
Динамическое распределение
Обычно принудительное установления срока жизни применяется в следующих ситуациях:
Указатели
Однако есть случаи, когда использование указателей оправдано не только с точки зрения динамического распределения памяти, но почти всегда есть альтернативный путь, без использования указателей, который вам и следует выбрать. Как и ранее, скажем: всегда делайте выбор в пользу альтернативы, если нет особенной необходимости в использовании указателей.
Случаями, когда использование указателей можно рассматривать как возможный вариант, можно назвать следующие:
BestProg
Содержание
Поиск на других ресурсах:
1. Указательные типы. Обзор
В языке Паскаль указательные типы – это типы, которые предназначены для получения адреса элемента программы. С помощью указательных типов можно получить доступ к переменным и константам в программе. Значениями переменных и констант указательных типов является адрес оперативной памяти.
Различают следующие указательные типы:
2. Особенности использования указательных типов. Объявление указателя типа Pointer и ^
Кроме предопределенных идентификаторов типов ( Pointer ) разрешается объявлять указательный тип с помощью символа ^ по следующей общей форме:
Для получения адреса переменной используется конструкция вида
здесь variable – переменная некоторого типа.
Соответственно, операция присваивания указателю с именем p адреса переменной variable в общем случае выглядит следующим образом
здесь value – значение, которое присваивается переменной variable с помощью указателя p.
Операция присваивания выглядит следующим образом:
Пример.
4. Пример объявления указателей на различные типы и использование указательных типов Pointer и ^ для доступа к переменным
Результат выполнения программы
Стандартный тип Text используется для описания текстовых файлов. В общем случае объявление переменного типа Text выглядит следующим образом:
Указатель (программирование)
Указатель (пойнтер, англ. pointer ) — переменная, диапазон значений которой состоит из адресов ячеек памяти и специального значения — нулевого адреса. Значение нулевого адреса не является реальным адресом и используется только для обозначения того, что указатель в данный момент не может использоваться для обращения ни к какой ячейке памяти.
Указатели применяются в двух различных сферах. Во-первых, они позволяют использовать некоторые выгоды косвенной адресации, широко применяемой в программировании на языках ассемблера. Во-вторых, указатели предлагают метод динамического управления памятью: их можно использовать для доступа к области с динамическим размещением памяти, обычно называемой кучей, или динамической памятью. Переменные, размещаемые в куче, называются динамическими. Часто они не содержат связанных с ними идентификаторов, и ссылаться на них можно только с помощью указателей и ссылок.
Операции над указателями
Языки программирования, в которых предусмотрен тип указателей, содержат, как правило, две основные операции над ними: присваивание и разыменование. Первая из этих операций присваивает указателю некоторый адрес. Вторая служит для обращения к значению в памяти, на которое указывает указатель. Разыменование может быть явным и неявным, в большинстве современных языков программирования разыменование происходит только при явном указании.
В случае, если указатель хранит адрес какого-либо объекта, то говорят, что указатель ссылается или указывает на этот объект p.
Языки, предусматривающие использование указателей для управления динамической памятью, должны содержать оператор явного размещения переменных в памяти. В некоторых языках помимо этого оператора предусмотрен ещё и оператор явного удаления переменных из памяти. Обе эти операции часто принимают форму встроенных подпрограмм.
Нулевой указатель
Нулевой указатель − это указатель, хранящий специальное значение, используемое для того, чтобы показать, что данная переменная-указатель не ссылается (не указывает) ни на какой объект. В различных языках программирования представлен различными константами.
См. также
Полезное
Смотреть что такое «Указатель (программирование)» в других словарях:
Указатель (тип данных) — У этого термина существуют и другие значения, см. Указатель. Диаграмма указателей Указатель (пойнтер, англ. pointer) переменная, диапазон значений которой состоит из адресов ячеек памяти и специального значения нулевого адреса.… … Википедия
Класс (программирование) — У этого термина существуют и другие значения, см. Класс. Класс в программировании набор методов и функций. Другие абстрактные типы данных метаклассы, интерфейсы, структуры, перечисления характеризуются какими то своими, другими… … Википедия
Шаблон (программирование) — Шаблоны (англ. template) средство языка C++, предназначенное для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например типам данных, размерам буферов, значениям по умолчанию). В C++ возможно создание шаблонов функций и … Википедия
Итератор (программирование) — Итератор (от англ. iterator) объект, позволяющий программисту перебирать все элементы коллекции без учёта особенностей её реализации. Итератор иногда также называют курсором, особенно если речь идет о базе данных. В Обероне он… … Википедия
Событийно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия
Callback (программирование) — У этого термина существуют и другие значения, см. Callback. Callback (англ. call вызов, англ. back обратный) или функция обратного вызова в программировании передача исполняемого кода в качестве одного из параметров… … Википедия
Интерфейс (объектно-ориентированное программирование) — У этого термина существуют и другие значения, см. Интерфейс (значения). Интерфейс (от лат. inter «между», и face «поверхность») семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования… … Википедия
Наследование (программирование) — Для улучшения этой статьи желательно?: Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное. У этого термин … Википедия
Граничный указатель — В области информатики граничный указатель (англ. bounded pointer) указатель, дополненный добавочной информацией, обозначающей границы хранилища, внутрь которого указатель может ссылаться. Эта дополнительная информация иногда приобретает вид… … Википедия
Динамическая переменная (программирование) — У этого термина существуют и другие значения, см. Динамическая переменная. Динамическая переменная переменная в программе, место в оперативной памяти под которую выделяется во время выполнения программы. По сути, она является даже не… … Википедия
POINTER
Pointer указка, указатель
Смотреть что такое POINTER в других словарях:
POINTER
[`pɔɪntə]указатель; указкастрелкапойнтернаводчикпастух, ведущий стадоподсказка, наводка, ЦУ, намекрычаг для перевода ручной стрелки
POINTER
pointer: translation noun 1 advice/indicationsADJECTIVE ▪ good, important ▪ clear, obvious ▪ practical, useful VERB + POINTER ▪ give (sb), offer (s. смотреть
POINTER
POINTER
POINTER
Pointer: übersetzung Zeigergerät; untraced Reference (fachsprachlich); freie Referenz; Referenz (fachsprachlich); Zeiger (fachsprachlich); Alias (fachs. смотреть
POINTER
I mпойнтер (порода собак)II vt1) отмечать точками, знаками; пунктировать; отмечать; регистрироватьpointer la carte — отмечать (местонахождение судна) н. смотреть
POINTER
POINTER
POINTER
<ʹpɔıntə>n 1. стрелка (часов, весов и т. п.); указатель (прибора)
POINTER
POINTER
POINTER
POINTER
pointer [ʹpɔıntə] n 1. стрелка (часов, весов и т. п.); указатель (прибора)
POINTER
POINTER
POINTER
сущ. 1) а) указатель; указка б) стрелка (какого-л. прибора) 2) а) пойнтер (порода собак) Syn: hound б) воен. наводчик в) пастух, ведущий стадо 3) а) разг. подсказка, наводка, ЦУ, намек Syn: hint, point, suggestion б) мн.; астр. альфа (Дубхе) и бета (Мерак) Большой Медведицы (находятся на одной линии с Полярной звездой, по ним и находят Полярную звезду) 4) а) сверла, резцы и другие подобные инструменты в каменотесном, гравировочном и подобных делах б) ж.-д. рычаг для перевода ручной стрелки 5) вид канадской лодки. смотреть
POINTER
n1) покажчик; дороговказ2) стрілка (годинника)3) указка4) пойнтер (порода собаки)5) розм. своєчасний натяк6) pl астр. дві зірки Великої Ведмедиці (Вели. смотреть
POINTER
1. указатель 2. стрелка — bank pointer — barometric pointer — double pointer — drift pointer — glide slope pointer — localizer deviation pointer — sp. смотреть
POINTER
POINTER
• *Piece of advice • I’m So Excited sisters • Complex protein indicator (7) • First finger • Hunting dog • Laser device • Last name of singers June, R. смотреть
POINTER
1) пойнтер (порода собак) 2) акула-людоед (Carcharodon) •- blue pointer- white pointer* * *акула-людоед
POINTER
n 1) покажчик (приладу); 2) стрілка (годинника тощо); 3) указка; 4) розм. натяк; 5) військ. навідник; 6) дороговказ; 7) пойнтер (порода собаки); 8) pl (Pointers) астр. дві зірки Великого Воза (Великої Ведмедиці) (що розташовані на одній лінії з Полярною зіркою). смотреть
POINTER
n1) покажчик2) військ. наводчик [навідник]
POINTER
1) центровать; накернивать2) размечать3) заострять4) прихватывать (детали) точечной сваркой
POINTER
Rzeczownik pointer m пойнтер m
POINTER
стрелка; указатель- bar pointer- hand pointer- heavy-duty power pointer- power pointer- push pointer- squeeze pointer- tube pointer- wire pointer
POINTER
1) указатель; ссылка2) гравировальная игла; резец для гравирования- em rack pointer
POINTER
POINTER
указатель; стрелка (часов и т. п.); указка пойнтер (порода собак); наводчик coll. своевременный намек, указание (pl.) astr. две звезды Большой Медведицы, находящиеся на одной линии с Полярной звездой. смотреть
POINTER
1. стрелка 2. указатель * * *стрелка, указатель
POINTER
Указатели в C++
Так как указатель содержит адрес объекта, это дает возможность «косвенного» доступа к этому объекту через указатель.
Указатели и массивы
приводит к тому, что pa указывает на нулевой элемент массива a. Это означает, что pa содержит адрес элемента a[0]. Теперь присваивание
будет копировать содержимое a[0] в x.
Если ра указывает на некоторый определенный элемент массива a, то по определению pa+1 указывает на следующий элемент, и вообще pa-i указывает на элемент, стоящий на i позиций до элемента, указываемого pa, а pa+i на элемент, стоящий на i позиций после. Таким образом, если pa указывает на a[0], то *(pa+1)
Эти замечания справедливы независимо от типа переменных в массиве a. Суть определения «добавления 1 к указателю», а также его распространения на всю арифметику указателей, состоит в том, что приращение масштабируется размером памяти, занимаемой объектом, на который указывает указатель. Таким образом, i в pa+i перед прибавлением умножается на размер объектов, на которые указывает pa.
Очевидно существует очень тесное соответствие между индексацией и арифметикой указателей. В действительности компилятор преобразует ссылку на массив в указатель на начало массива. В результате этого имя массива является указательным выражением. Отсюда вытекает несколько весьма полезных следствий. Так как имя массива является синонимом местоположения его нулевого элемента, то присваивание pa = &a[0]
можно записать как pa = a.
Когда имя массива передается функции, то на самом деле ей передается местоположение начала этого массива. Внутри вызванной функции такой аргумент является точно такой же переменной, как и любая другая, так что имя массива в качестве аргумента действительно является указателем, т.е. переменной, содержащей адрес. Мы можем использовать это обстоятельство для написания нового варианта функции strlen, вычисляющей длину строки: /* возвращает длину строки s */
Операция увеличения s совершенно законна, поскольку эта переменная является указателем, s++ никак не влияет на символьную строку в обратившейся к strlen функции, а только увеличивает локальную для функции strlen копию адреса.
Описания формальных параметров в определении функции в виде char s[];
совершенно эквивалентны; какой вид описания следует предпочесть, определяется в значительной степени тем, какие выражения будут использованы при написании функции. Если функции передается имя массива, то в зависимости от того, что удобнее, можно полагать, что функция оперирует либо с массивом, либо с указателем, и действовать далее соответвующим образом. Можно даже использовать оба вида операций, если это кажется уместным и ясным.
Следствием такой интерпретации имен массивов является то, что для того чтобы поставить указатель на начало массива, надо писать
Как описывать ссылки (указатели) на двумерные массивы?
Как описывать ссылки (указатели) на двумерные массивы? Рассмотрим такую программу:
Указателем здесь является ptr. Отметим, что у него задана размерность по второму измерению: Second, именно для того, чтобы компилятор мог правильно вычислить двумерные индексы.
Попробуйте сами объявить
и увидеть, к каким невеселым эффектам это приведет (компилятор, кстати, будет ругаться; но есть вероятность, что он все же странслирует это для вас. Но работать оно будет плачевно). Попробуйте также использовать ptr[x][y].
Обратите также внимание на инициализацию строк в нашем примере. Строка «ABC.» равносильна объявлению
Указатели на функции
Например, используется в функции: Быстрая сортировка (англ. quicksort), часто называемая qsort. В функции qsort указатель на функцию применяется для указания способа сортировки.
Прежде чем вводить указатель на функцию, напомним, что каждая функция характеризуется типом возвращаемого значения, именем и сигнатурой. Напомним, что сигнатура определяется количеством, порядком следования и типами параметров. Иногда говорят, что сигнатурой функции называется список типов ее параметров.
А теперь путём последовательности утверждений придем к обсуждению темы данного раздела урока.
1. При использовании имени функции без последующих скобок и параметров имя функции выступает в качестве указателя на эту функцию, и его значением служит адрес размещения функции в памяти.
2. Это значение адреса может быть присвоено некоторому указателю, и затем уже этот новый указатель можно применять для вызова функции.
3. В определении нового указателя должен быть тот же тип, что и возвращаемое функцией значение, и та же сигнатура.
4. Указатель на функцию определяется следующим образом:
Иллюстрируем на практике. В определении указателя на функцию тип возвращаемого значения и сигнатура (типы, количество и последовательность параметров) должны совпадать с соответствующими типами и сигнатурами тех функций, адреса которых предполагается присваивать вводимому указателю при инициализации или с помощью оператора присваивания. В качестве простейшей иллюстрации сказанного приведем программу с указателем на функцию:
Результат выполнения программы:
Здесь значением имени_указателя служит адрес функции, а с помощью операции разыменования * обеспечивается обращение по адресу к этой функции. Однако будет ошибкой записать вызов функции без скобок в виде *ptr();. Дело в том, что операция () имеет более высокий приоритет, нежели операция обращения по адресу *. Следовательно, в соответствии с синтаксисом будет вначале сделана попытка обратиться к функции ptr(). И уже к результату будет отнесена операция разыменования, что будет воспринято как синтаксическая ошибка.
При определении указатель на функцию может быть инициализирован. В качестве инициализирующего значения должен использоваться адрес функции, тип и сигнатура которой соответствуют определяемому указателю.
При присваивании указателей на функции также необходимо соблюдать соответствие типов возвращаемых значений функций и сигнатур для указателей правой и левой частей оператора присваивания. То же справедливо и при последующем вызове функций с помощью указателей, т.е. типы и количество фактических параметров, используемых при обращении к функции по адресу, должны соответствовать формальным параметрам вызываемой функции. Например, только некоторые из следующих операторов будут допустимы:
Следующая программа отражает гибкость механизма вызовов функций с помощью указателей.
Результаты выполнения программы:
Цикл продолжается, пока значением переменной c не станет пробел. В каждой итерации указатель par получает адрес одной из функций, и изменяется значение c. По результатам программы легко проследить порядок выполнения ее операторов.
Как обычно, индексация массива начинается с 0, и поэтому третий элемент массива имеет индекс 2.
Массивы указателей на функции удобно использовать при разработке всевозможных меню, точнее программ, управление которыми выполняется с помощью меню. Для этого действия, предлагаемые на выбор будущему пользователю программы, оформляются в виде функций, адреса которых помещаются в массив указателей на функции. Пользователю предлагается выбрать из меню нужный ему пункт (в простейшем случае он вводит номер выбираемого пункта) и по номеру пункта, как по индексу, из массива выбирается соответствующий адрес функции. Обращение к функции по этому адресу обеспечивает выполнение требуемых действий. Самую общую схему реализации такого подхода иллюстрирует следующая программа для «обработки файлов»: