Справочник (информатика)
Эта статья нуждается в дополнительных цитатах для проверки . ( ноябрь 2010 г. ) |
В компьютерном программировании ссылка — это значение, которое позволяет программе косвенно обращаться к определенным данным , таким как значение переменной или запись , в компьютера устройстве памяти или на каком-либо другом хранения данных . Говорят, что ссылка ссылается на данные, а доступ к данным называется разыменованием ссылки. Ссылка отличается от самих данных.
Ссылка представляет собой абстрактный тип данных и может быть реализована разными способами. Обычно ссылка относится к данным, хранящимся в памяти данной системы, а ее внутреннее значение — это адрес данных в памяти , т. е. ссылка реализуется как указатель . По этой причине часто говорят, что ссылка «указывает» на данные. Другие реализации включают смещение (разницу) между адресом данных и некоторым фиксированным «базовым» адресом, индексом или идентификатором, используемым в операции поиска в массиве или таблице операционной системы , дескриптор , физический адрес на устройстве хранения или сетевой адрес, например URL-адрес .
Официальное представительство
[ редактировать ]Ссылка R — это значение, допускающее одну операцию: dereference( R ), что дает значение. Обычно ссылка типизируется так, что возвращает значения определенного типа, например: [1] [2]
interface Reference<T> {
T value();
}
Часто ссылка также допускает операцию присваивания. store( R , x ), что означает, что это абстрактная переменная . [1]
Использовать
[ редактировать ]Ссылки широко используются в или для совместного использования программировании, особенно для эффективной передачи больших или изменяемых данных в качестве аргументов процедурам таких данных между различными пользователями. В частности, ссылка может указывать на переменную или запись, содержащую ссылки на другие данные. Эта идея лежит в основе косвенной адресации и многих связанных структур данных , таких как связанные списки . Ссылки повышают гибкость в выборе места хранения объектов, их распределения и передачи между областями кода . Пока можно получить доступ к ссылке на данные, можно получить доступ к данным через нее, и сами данные не нужно перемещать. Они также упрощают обмен данными между различными областями кода; каждый хранит ссылку на него.
Ссылки могут вызвать значительную сложность в программе, частично из-за возможности висячих и диких ссылок , а частично из-за того, что топология данных со ссылками представляет собой ориентированный граф , анализ которого может быть достаточно сложным. Тем не менее, ссылки по-прежнему проще анализировать, чем указатели, из-за отсутствия арифметики указателей .
Механизм ссылок, хотя и различается по реализации, является фундаментальной особенностью языка программирования, общей почти для всех современных языков программирования. Даже некоторые языки, которые не поддерживают прямое использование ссылок, имеют некоторое внутреннее или неявное использование. Например, соглашение о вызове по ссылке может быть реализовано как с явным, так и с неявным использованием ссылок.
Примеры
[ редактировать ]Указатели — это самый примитивный тип ссылок. Благодаря своей тесной связи с базовым оборудованием они являются одним из наиболее мощных и эффективных типов ссылок. Однако из-за этой взаимосвязи указатели требуют от программиста глубокого понимания деталей архитектуры памяти. Поскольку указатели хранят адрес ячейки памяти, а не непосредственно значение, неправильное использование указателей может привести к неопределенному поведению в программе, особенно из-за висячих указателей или диких указателей . Интеллектуальные указатели — это непрозрачные структуры данных , которые действуют как указатели, но доступны только с помощью определенных методов.
Дескриптор представляет собой абстрактную ссылку и может быть представлен различными способами. Типичным примером являются дескрипторы файлов (структура данных FILE в стандартной библиотеке ввода-вывода C ), используемые для абстрагирования содержимого файла. Обычно он представляет как сам файл, как при запросе блокировки файла, так и определенную позицию в содержимом файла, как при чтении файла.
В распределенных вычислениях ссылка может содержать не только адрес или идентификатор; он также может включать встроенную спецификацию сетевых протоколов, используемых для обнаружения и доступа к указанному объекту, а также способа кодирования или сериализации информации. Так, например, WSDL- описание удаленной веб-службы можно рассматривать как форму ссылки; он включает в себя полную спецификацию того, как найти конкретную веб-службу и привязать ее к ней . Ссылка на действующий распределенный объект является еще одним примером: это полная спецификация того, как создать небольшой программный компонент, называемый прокси , который впоследствии будет участвовать в одноранговом взаимодействии и через который локальная машина может получить доступ к данные, которые реплицируются или существуют только в виде слабо согласованного потока сообщений. Во всех этих случаях ссылка включает полный набор инструкций или рецепт доступа к данным; в этом смысле он служит той же цели, что и идентификатор или адрес в памяти.
Если у нас есть набор ключей K и набор объектов данных D , любая четко определенная (однозначная) функция от K до D ∪ { null } определяет тип ссылки, где null — это изображение ключа, не ссылающегося на ни к чему значимому.
Альтернативным представлением такой функции является ориентированный граф, называемый графом достижимости . Здесь каждый элемент данных представлен вершиной, и существует ребро от u до v , если элемент данных в u относится к элементу данных в v . Максимальная степень выхода равна единице. Эти графы полезны при сборке мусора , где их можно использовать для отделения доступных объектов от недоступных .
Внешняя и внутренняя память
[ редактировать ]Во многих структурах данных большие и сложные объекты состоят из более мелких объектов. Эти объекты обычно хранятся одним из двух способов:
- При использовании внутреннего хранилища содержимое меньшего объекта хранится внутри более крупного объекта.
- При внешнем хранилище меньшие объекты размещаются в своем собственном расположении, а более крупный объект хранит только ссылки на них.
требуется место Внутреннее хранилище обычно более эффективно, поскольку для ссылок и метаданных динамического выделения , а также затраты времени, связанные с разыменованием ссылки и выделением памяти для более мелких объектов. Внутреннее хранилище также повышает локальность ссылок , сохраняя в памяти разные части одного и того же большого объекта близко друг к другу. Однако существует множество ситуаций, в которых внешнее хранилище предпочтительнее:
- Если структура данных рекурсивная , это означает, что она может содержать саму себя. Это невозможно представить внутренним образом.
- Если более крупный объект хранится в области с ограниченным пространством, например в стеке, мы можем предотвратить нехватку памяти, сохраняя большие объекты-компоненты в другой области памяти и обращаясь к ним с помощью ссылок.
- Если меньшие объекты могут различаться по размеру, часто бывает неудобно или дорого изменять размер более крупного объекта, чтобы он все еще мог их содержать.
- Со ссылками часто легче работать, и они лучше адаптируются к новым требованиям.
Некоторые языки, такие как Java , Smalltalk , Python и Scheme , не поддерживают внутреннюю память. В этих языках доступ ко всем объектам осуществляется через ссылки.
Языковая поддержка
[ редактировать ]Сборка
[ редактировать ]В языке ассемблера ссылки обычно выражаются с использованием необработанных адресов памяти или индексов в таблицах. Они работают, но их несколько сложно использовать, поскольку адрес ничего не говорит вам о значении, на которое он указывает, даже о том, насколько он велик или как его интерпретировать; такая информация закодирована в логике программы. В результате в неправильных программах могут возникать неверные интерпретации, вызывающие сбивающие с толку ошибки.
Лисп
[ редактировать ]Одной из самых ранних непрозрачных ссылок была ссылка на Лисп языка cons-ячейку , которая представляет собой просто запись, содержащую две ссылки на другие объекты Лиспа, включая, возможно, другие cons-ячейки. Эта простая структура чаще всего используется для построения односвязных списков , но также может использоваться для построения простых двоичных деревьев и так называемых «пунктирных списков», которые завершаются не нулевой ссылкой, а значением.
С/С++
[ редактировать ]Указатель по - прежнему остается одним из самых популярных типов ссылок сегодня. Оно похоже на ассемблерное представление необработанного адреса, за исключением того, что оно содержит статический тип данных , который можно использовать во время компиляции, чтобы гарантировать, что данные, на которые он ссылается, не будут неправильно интерпретированы. Однако, поскольку C имеет слабую систему типов , которую можно нарушить с помощью приведения (явного преобразования между различными типами указателей, а также между типами указателей и целыми числами), неправильная интерпретация все еще возможна, хотя и более сложна. Его преемник C++ пытался повысить безопасность типов указателей с помощью новых операторов приведения, ссылочного типа. &
и интеллектуальные указатели в своей стандартной библиотеке , но по-прежнему сохранял возможность обходить эти механизмы безопасности для совместимости.
Фортран
[ редактировать ]Фортран не имеет явного представления ссылок, но использует их неявно в своей семантике вызова по ссылке . Ссылку на Фортране лучше всего рассматривать как псевдоним другого объекта, например скалярной переменной, строки или столбца массива. Не существует синтаксиса для разыменования ссылки или непосредственного управления содержимым референта. Ссылки Фортрана могут быть нулевыми. Как и в других языках, эти ссылки облегчают обработку динамических структур, таких как связанные списки, очереди и деревья.
Объектно-ориентированные языки
[ редактировать ]Ряд объектно-ориентированных языков, таких как Eiffel , Java , C# и Visual Basic , приняли гораздо более непрозрачный тип ссылки, обычно называемый просто ссылкой . Эти ссылки имеют типы, подобные указателям C, указывающие, как интерпретировать данные, на которые они ссылаются, но они типобезопасны, поскольку их нельзя интерпретировать как необработанный адрес, а небезопасные преобразования не допускаются. Ссылки широко используются для доступа к объектам и их назначения . Ссылки также используются при функций/ методов вызовах или передаче сообщений, а счетчики ссылок часто используются для выполнения сборки мусора неиспользуемых объектов.
Функциональные языки
[ редактировать ]В Standard ML , OCaml и многих других функциональных языках большинство значений являются постоянными: их нельзя изменить путем присвоения. Назначаемые «эталонные ячейки» предоставляют изменяемые переменные — данные, которые можно изменить. Такие ссылочные ячейки могут содержать любое значение, поэтому им присваивается полиморфный тип. α ref
, где α
должен быть заменен типом указанного значения. Эти изменяемые ссылки могут указывать на разные объекты в течение их жизни. Например, это позволяет создавать циклические структуры данных. Эталонная ячейка функционально эквивалентна изменяемому массиву длины 1.
Чтобы сохранить безопасность и эффективность реализации, в ML нельзя приводить ссылки к типам , а также нельзя выполнять арифметику указателей. В функциональной парадигме многие структуры, которые в таком языке, как C, могут быть представлены с помощью указателей, представлены с использованием других средств, таких как мощный механизм алгебраических типов данных . Тогда программист может пользоваться определенными свойствами (например, гарантией неизменности) во время программирования, даже несмотря на то, что компилятор часто использует машинные указатели «под капотом».
Перл/PHP
[ редактировать ]Perl поддерживает жесткие ссылки, которые действуют аналогично ссылкам в других языках, и символические ссылки , которые представляют собой просто строковые значения, содержащие имена переменных. Когда разыменовывается значение, не являющееся жесткой ссылкой, Perl считает его символической ссылкой и присваивает переменной имя, заданное значением. [3] PHP имеет аналогичную функцию в виде $$var
синтаксис. [4]
Питон
[ редактировать ]Python включает в себя широкий спектр ссылок. Обычно программисты используют id(var)
для доступа к ссылочному адресу переменной var
. Ссылка на Python более сложна, чем на C++ или других языках программирования.
Константа (например, целое число 2) является объектом в Python и, следовательно, имеет ссылку на фиксированный адрес. Когда программист вызывает a = 2
, программа создает пространство памяти для согласных 2
и организует ссылку на него. Затем программа связывает ссылку a
по адресу 2
, который показывает, что изменение значения числовой переменной приводит к изменению ее ссылки. В то время как в изменяемых типах (например, list
type), изменение значения не приведет к изменению ссылки на переменную.
Когда переменная передается в качестве параметра функции, функция по умолчанию получает ссылку на нее, а не на ее значение. Для изменяемых типов это позволяет легко изменить исходную переменную; для неизменяемого типа изменение его значения в функции приведет к изменению ссылки на временную переменную в функции в другое место, следовательно, не приведет к изменению исходной переменной.
См. также
[ редактировать ]- Абстракция (информатика)
- Автовивификация
- Ограниченный указатель
- Связанные данные
- Волшебное печенье
- Слабая ссылка
Ссылки
[ редактировать ]- ^ Перейти обратно: а б Шерман, Марк С. (апрель 1985 г.). Paragon: язык, использующий иерархии типов для спецификации, реализации и выбора абстрактных типов данных . Springer Science & Business Media. п. 175. ИСБН 978-3-540-15212-5 .
- ^ «Справочник (платформа Java SE 7)» . docs.oracle.com . Проверено 10 мая 2022 г.
- ^ "перлреф" . perldoc.perl.org . Проверено 19 августа 2013 г.
- ^ «Переменные переменные — Руководство» . PHP . Проверено 19 августа 2013 г.
Внешние ссылки
[ редактировать ]- Указательное развлечение с Бинки. Знакомство с указателями в 3-минутном обучающем видео - Стэнфордская образовательная библиотека информатики