Указатели
Указатели представляют собой объекты, значением которых служат адреса других объектов (переменных, констант, указателей) или функций. Как и ссылки, указатели применяются для косвенного доступа к объекту. Однако в отличие от ссылок указатели обладают большими возможностями.
Определение указателя
Для определения указателя надо указать тип объекта, на который указывает указатель, и символ звездочки *:
тип_данных* название_указателя;
Сначала идет тип данных, на который указывает указатель, и символ звездочки *. Затем имя указателя.
Например, определим указатель на объект типа int:
int* p;
Такой указатель может хранить только адрес переменной типа int , но пока данный указатель не ссылается ни на какой объект и хранит случайное значение. Мы его даже можем попробовать вывести на консоль:
#include int main()
Например, в моем случае консоль вывела «0x8» — некоторый адрес в шестнадцатеричном формате (обычно для представления адресов в памяти применяется шестнадцатеричная форма). Но также можно инициализировать указатель некоторым значением:
int* p<>;
Поскольку конкрентное значение не указано, указатель в качестве значения получает число 0. Это значение представляет специальный адрес, который не указывает не на что. Также можно явным образом инициализировать нулем, например, используя специальную константу nullptr :
int* p;
Хотя никто не запрещает не инициализировать указатели. Однако в общем случае рекомендуется все таки инициализировать, либо каким-то конкретным значением, либо нулем, как выше. Так, к примеру, нулевое значение в будущем позволит определить, что указатель не указывает ни на какой объект.
Cтоит отметить что положение звездочки не влияет на определение указателя: ее можно помещать ближе к типу данных, либо к имени переменной — оба определения будут равноценны:
int* p1<>; int *p2<>;
Также стоит отметить, что размер значения указателя (хранимый адрес) не зависит от типа указателя. Он зависит от конкретной платформы. На 32-разрядных платформах размер адресов равен 4 байтам, а на 64-разрядных — 8 байтам. Например:
#include int main() < int *pint<>; double *pdouble<>; std::cout
В данном случае определены два указателя на разные типы — int и double. Переменные этих типов имеют разные размеры — 4 и 8 байт соответственно. Но размеры значений указателей будут одинаковы. В моем случае на 64-разрядной платформе размер обоих указателей равен 8 байтам.
Получение адреса и оператор &
С помощью операция & можно получить адрес некоторого объекта, например, адрес переменной. Затем этот адрес можно присвоить указателю::
int number ; int *pnumber ; // указатель pnumber хранит адрес переменной number
Выражение &number возвращает адрес переменной number . Поэтому переменная pnumber будет хранить адрес переменной number . Что важно, переменная number имеет тип int, и указатель, который указывает на ее адрес, тоже имеет тип int. То есть должно быть соответствие по типу. Однако также можно использовать ключевое слово auto :
int number ; auto *pnumber ; // указатель pnumber хранит адрес переменной number
Если мы попробуем вывести адрес переменной на консоль, то увидим, что он представляет шестнадцатиричное значение:
#include int main() < int number ; int *pnumber ; // указатель pnumber хранит адрес переменной number std::cout
Консольный вывод программы в моем случае:
number addr: 0x1543bffc74
В каждом отдельном случае адрес может отличаться и при разных запусках программы может меняться. К примеру, в моем случае машинный адрес переменной number — 0x1543bffc74 . То есть в памяти компьютера есть адрес 0x1543bffc74, по которому располагается переменная number. Так как переменная x представляет тип int , то на большинстве архитектур она будет занимать следующие 4 байта (на конкретных архитектурах размер памяти для типа int может отличаться). Таким образом, переменная типа int последовательно займет ячейки памяти с адресами 0x1543bffc74, 0x1543bffc75, 0x1543bffc76, 0x1543bffc77.
И указатель pnumber будет ссылаться на адрес, по которому располагается переменная number, то есть на адрес 0x1543bffc74.
Итак, указатель pnumber хранит адрес переменной number, а где хранится сам указатель pnumber? Чтобы узнать это, мы также можем применить к переменной pnumber операцию &:
#include int main() < int number ; int *pnumber ; // указатель pnumber хранит адрес переменной number std::cout
Консольный вывод программы в моем случае:
number addr: 0xe1f99ff7cc pnumber addr: 0xe1f99ff7c0
Здесь мы видим, что переменная number располагается по адресу 0xe1f99ff7cc , а указатель, который хранит этот адрес, — по адресу 0xe1f99ff7c0 . Из вывода видно, что обе переменные хранятся совсем рядом в памяти
Получение значения по адресу
Но так как указатель хранит адрес, то мы можем по этому адресу получить хранящееся там значение, то есть значение переменной number. Для этого применяется операция * или операция разыменования («indirection operator» / «dereference operator»). Результатом этой операции всегда является объект, на который указывает указатель. Применим данную операцию и получим значение переменной number:
#include int main() < int number ; int *pnumber ; std::cout Address = 0x44305ffd4c Value = 25
Значение, которое получено в результате операции разыменования, можно присвоить другой переменной:
int n1 ; int *pn1 ; // указатель pn1 хранит адрес переменной n1 int n2 < *pn1>; // n2 получает значение, которое хранится по адресу в pn1 std::cout int x = 10; int *px = &x; *px = 45; std::cout
Указатель (программирование)
Указатель (пойнтер, англ. pointer ) — переменная, диапазон значений которой состоит из адресов ячеек памяти и специального значения — нулевого адреса. Значение нулевого адреса не является реальным адресом и используется только для обозначения того, что указатель в данный момент не может использоваться для обращения ни к какой ячейке памяти.
Указатели применяются в двух различных сферах. Во-первых, они позволяют использовать некоторые выгоды косвенной адресации, широко применяемой в программировании на языках ассемблера. Во-вторых, указатели предлагают метод динамического управления памятью: их можно использовать для доступа к области с динамическим размещением памяти, обычно называемой кучей, или динамической памятью. Переменные, размещаемые в куче, называются динамическими. Часто они не содержат связанных с ними идентификаторов, и ссылаться на них можно только с помощью указателей и ссылок.
Операции над указателями
Языки программирования, в которых предусмотрен тип указателей, содержат, как правило, две основные операции над ними: присваивание и разыменование. Первая из этих операций присваивает указателю некоторый адрес. Вторая служит для обращения к значению в памяти, на которое указывает указатель. Разыменование может быть явным и неявным, в большинстве современных языков программирования разыменование происходит только при явном указании.
В случае, если указатель хранит адрес какого-либо объекта, то говорят, что указатель ссылается или указывает на этот объект p.
Языки, предусматривающие использование указателей для управления динамической памятью, должны содержать оператор явного размещения переменных в памяти. В некоторых языках помимо этого оператора предусмотрен ещё и оператор явного удаления переменных из памяти. Обе эти операции часто принимают форму встроенных подпрограмм.
Нулевой указатель
Нулевой указатель − это указатель, хранящий специальное значение, используемое для того, чтобы показать, что данная переменная-указатель не ссылается (не указывает) ни на какой объект. В различных языках программирования представлен различными константами.
См. также
Wikimedia Foundation . 2010 .
Значение слова «указатель»
Источник (печатная версия): Словарь русского языка: В 4-х т. / РАН, Ин-т лингвистич. исследований; Под ред. А. П. Евгеньевой. — 4-е изд., стер. — М.: Рус. яз.; Полиграфресурсы, 1999; (электронная версия): Фундаментальная электронная библиотека
- Указатель (тип данных) — в программировании
Указатель в графических интерфейсах пользователя — тип курсора
Дорожный знак, и в более узком смысле дорожные указатели и их предшественники (Fingerpost).
- УКАЗА'ТЕЛЬ, я, м.1. Приспособление, служащее для указания чего-н.: надпись, веха, стрелка и т. п. У. дорог.2. Книга, содержащая справочные сведения из какой-н. области. Железнодорожный у. Библиографический у.3. Оглавление или какой-н. справочный список в книге. У. собственных имен. У. цитируемых сочинений.4. Величина, характеризующая форму частей тела (антр.).
Источник: «Толковый словарь русского языка» под редакцией Д. Н. Ушакова (1935-1940); (электронная версия): Фундаментальная электронная библиотека
указа́тель
Делаем Карту слов лучше вместе
Привет! Меня зовут Лампобот, я компьютерная программа, которая помогает делать Карту слов. Я отлично умею считать, но пока плохо понимаю, как устроен ваш мир. Помоги мне разобраться!
Спасибо! Я стал чуточку лучше понимать мир эмоций.
Вопрос: кейфовать — это что-то нейтральное, положительное или отрицательное?
Нейтральное
Положительное
Отрицательное
Ассоциации к слову «указатель»
Синонимы к слову «указатель»
Предложения со словом «указатель»
- Идя далее по воображаемому маршруту, вы видите дорожный указатель, на котором вместо знака висит зеркало, а пройдя мимо него, видите качели, на которых тают разноцветные шарики мороженого.
Цитаты из русской классики со словом «указатель»
- Прочтите-ка в «Экономическом указателе» [«Экономический указатель» — еженедельный журнал, издававшийся И. В. Вернадским с 1857 г.
Сочетаемость слова «указатель»
- дорожный указатель
алфавитный указатель
именной указатель - указатель мыши
указатель поворота
указатель скорости - стрелка указателя
при наведении указателя мыши
в поисках указателей - указатель сообщал
указатель показывает
указатель гласил - увидеть указатель
посмотреть на указатель
судя по указателям - (полная таблица сочетаемости)
Каким бывает «указатель»
Понятия со словом «указатель»
Указатель — это справочный текст, который выглядит как список ключевых слов и страниц, где они упомянуты.
Библиографический указатель — общий термин для обозначения нескольких видов библиографических пособий (см.: Библиография), то есть списков опубликованных документов (книг, газетных и журнальных статей и т. п.), объединенных каким-либо признаком и снабжённых вспомогательными индексами, облегчающими поиск и группировку материалов.
Афоризмы русских писателей со словом «указатель»
- Религии суть указатели того высшего, доступного в данное время и в данном обществе лучшими передовыми людьми, понимания жизни, к которому неизбежно и неизменно приближаются все остальные люди этого общества.
Отправить комментарий
Дополнительно
- Как правильно пишется слово «указатель»
- Склонение существительного «указатель» (изменение по числам и падежам)
- Разбор по составу слова «указатель» (морфемный разбор)
- Цитаты со словом «указатель» (подборка цитат)
- Перевод слова «указатель» и примеры предложений (английский язык)
- Definition of «pointer» at WordTools.ai (английский язык)
Смотрите также
Предложения со словом «указатель»
- Идя далее по воображаемому маршруту, вы видите дорожный указатель, на котором вместо знака висит зеркало, а пройдя мимо него, видите качели, на которых тают разноцветные шарики мороженого.
- – Стоит увидеть указатели, как сам амбар становится невидимым.
- Стройка, сужение, дальше гравий, изъезженный грейдерами, на котором автомобиль не на шутку трясётся и без помощи водителя включает указатели поворотов и дворники, поднимая при этом столбы пыли.
- (все предложения)
Синонимы к слову «указатель»
Ассоциации к слову «указатель»
Сочетаемость слова «указатель»
- дорожный указатель
- указатель мыши
- стрелка указателя
- указатель сообщал
- увидеть указатель
- (полная таблица сочетаемости. )
Что такое указатель
Наиболее интересное, что есть в языках С и С++ — это указатели. Без понимания принципов работы с указателями нельзя научиться работать на этих двух языках. Справедливости ради надо заметить, что указатели в С++ можно применять реже, чем в С, решая при этом одни и те же задачи. Например, если надо смоделировать работу сложной динамической структуры, то в С++ есть возможность применить какой-нибудь из стандартных классов STL (Стандартная библиотека шаблонов), а в С всё приходится делать самому, используя указатели.
Понятие указателя
Любая программа, как известно, предназначена для обработки данных. Все данные условно можно подразделить на собственно данные (числа, строки и т.д.) и на адреса в оперативной памяти, где хранятся эти данные. Мы оперируем в программе именами переменных, но для исполнения программы процессором компьютера все имена ещё на этапе компиляции заменены на адреса. Поэтому компьютер работает либо с неким данным, либо с адресом, где хранится это данное. И ничего другого просто нет. Для выполнения различных действий с адресами служат указатели.
Указатель — это беззнаковое целое, используемое для хранения адреса какого-либо участка памяти.
Указатель всегда является переменной величиной. Указатели в 16-разрядной операционной системе MS DOS так же были 16-разрядными. В настоящее время обычно используются 32-разрядные операционные системы (Windows, Linux и др.), в которых указатели занимают 4 байта (32-разрядное целое без знака). И хотя это по внутреннему представлению в точности соответствует типу unsigned int , но указатель и переменная типа unsigned int — это две большие разницы.
Всякий указатель используется для работы с данными, которые имеют какой-то свой тип и, соответственно , свой размер, например, double или int . Следовательно, при описании указателя необходимо сказать, на объекты какого типа он будет настроен.
Формальное описание указателя такое:
Тип_данных — любой ранее определённый тип (стандартный или пользовательский);
* — знак «звёздочка» здесь является признаком того, что речь идёт об указателе;
Имя_указателя — определяется по общим правилам (как для любого идентификатора пользователя).
Дадим описание указателя для работы с данными типа double :
Данную запись необходимо понимать так: « u — это указатель на объект типа double ».
На какой объект настроен этот указатель? В данный момент ни на какой. Значение указателя u в момент выделения памяти не определено.
Пусть имеется переменная a типа double :
Настроим указатель u на эту переменную a :
Здесь знак & означает вычисление адреса, т.е. мы вычисляем адрес переменной a и записываем его в ячейку u . Пусть a находится по адресу 1000 . Вот это число-адрес и станет содержимым u . Теперь указатель u настроен на начальный адрес переменной a . Что это нам даёт? Не много — не мало, а доступ к содержимому переменной a , если применить операцию разыменования:
Этим оператором мы выводим на экран монитора содержимое переменной a , т.к. указатель u настроен на эту же переменную a .
Можно и изменить значение переменной a , используя указатель u :
На экране будет выведено число 11.3 , хотя ранее переменная a имела значение 2.5 . Следовательно, пользуясь указателем, мы действительно изменили содержимое переменной a .
Рассмотренный пример работы с указателем особой ценности не имеет и служит лишь для демонстрации работы с указателями.
Операции для работы с указателями
Хотя всякий указатель по внутреннему представлению — это беззнаковое целое, но по характеру операций он заметно отличается от любых целых типов. Рассмотрим все операции, допустимые для указателей.
1. Присваивание ( = ). Указателю можно присвоить адрес какой-то переменной или значение другого указателя. Приведем пример:
u = &a; // Указатель u настроен на переменную a
v = u; // Теперь и указатель v настроен на переменную a
2. Разыменование ( * ) — эта унарная операция позволяет обратиться к ячейке памяти, на которую предварительно настроен указатель. Например:
Теперь значение переменной a равно 4.5 .
3. Вычисление адреса ( & ).
v = &b; // Теперь указатель v настроен на переменную b.
Для переменной любого числового типа автоувеличение означает увеличение на 1 значения того, что было в ячейке, например:
i++; // Теперь i равно 6.
Для указателя операция автоувеличения означает переключение на следующий объект того же типа, что и тип, на который был настроен указатель. Пусть имеется массив x из трёх чисел типа double и указатель u на тип double :
А теперь поработаем с массивом через указатель (см. так же рисунок ниже):
u = &x[0]; // настроим указатель u на начало массива
u++; // переключаемся на 1 объект вправо, т.е. на x[1]
Как видим, автоувеличение даёт смещение на 1 один объект, а в байтах для указателя на тип double это будет равно 8 (т.е. смещаемся на 8 байт). Таким образом, адрес, хранящийся в указателе u , за счёт выполнения операции автоувеличения ( ++ ), увеличится на 8 .
Подобная картина будет и для указателей на другие типы, например: для указателя на тип int шаг смещения при автоувеличении равен 4 . Только для указателей на объекты размером в один байт (например, на char ) величина смещения будет равна 1 байту, что соответствует обычному представлению об операции автоувеличения.
Здесь всё аналогично тому, что было сказано об автоувеличении. Рассмотрите эту операцию самостоятельно.
К указателю можно прибавить целое число. Если сложение сопоставить с автоувеличением, то несложно понять, что операторы
приводят к смещению указателя v на 2 объекта вправо, т.е. адрес, записанный в v , увеличится на 16 ( 2*8 = 16 ). будет напечатано число 7 (см. рис. выше).
Но нельзя складывать два указателя . Попытка сделать это бессмысленна по своей сути (что может означать сумма значений двух указателей?), поэтому она просто запрещена.
Для указателей допустимо как вычитание числа из указателя, так и определение разности двух указателей.
double *u = &x[2]; // Настроить указатель
// на 2-й элемент массива
int k = 2; // Пусть это будет смещением
u = u – k; // Смещаем влево значение указателя
// на k объектов типа double
// Далее какие-то действия
Теперь k определяет расстояние между объектами в памяти, на которые были предварительно настроены указатели.
8. Умножение, деление и вычисление остатка для указателей бессмысленны, а потому запрещены.
9. Операции сравнения . Для указателей допустимы все без исключения операции сравнения. Чаще всего используется проверка на равенство ( == ) и на неравенство ( != ). Пример:
// Можно работать с указателем. К примеру, так:
//Работа с указателем невозможна
10. Логические операции для указателей не применяют, но оператор типа
ошибки не вызывает, хотя трудно придать смысл такой записи.
Область применения указателей
Используя механизм указателей, можно решать самые разнообразные задачи. Чаще всего указатели используют для:
работы с массивами и особенно с массивами типа char ;
передачи данных в функцию по адресу;
построение сложных динамических структур данных.
Подробности использования указателей по перечисленным темам будут приведены в последующих темах.