|
|
|
| Разъясните мне простым языком, что такое указатели в c++ и где их удобно применять? | |
|
|
|
|
|
|
|
для: 123php
(30.10.2006 в 11:51)
| | Указатели в C++ это всё - даже не двигайтесь дальше пока не поймёте их до конца, иначе язык не поймёте. Т.е. нельзя не поняв указатели дальше пытаться изучать C++ - бесполезно.
Указатель - это специальная переменная, которая содержит адрес в памяти другой переменной. Пусть есть указатель prt, который указывает на переменную var.
//Получаем адрес переменной var при помощи &
int *prt = &var;
|
Если вы просто выводите указатель
cout << prt << "\n";
// Аналогоично можно получить адрес так
cout << &var << "\n";
|
вы получите адрес переменной var. Если вы производите операцию разыменования вы получаете содержимое var
cout << *prt << "\n";
// Аналогично
cout << var << "\n";
|
Я, обычно, когда объясняя указатели вот такую таблицу рисую
| адрес | значение |
------------|---------|-----------|
указатель | prt | *prt |
------------|---------|-----------|
переменная | &var | var |
------------|---------|-----------|
|
В таблице всё относится к переменной и её адрес и значение.
Вы можете получить адрес и указателя
В этом случае p - будет двойным указателем, который обычно объявляется следующим образом
Получить значение к переменной var по двойному указателю можно, если произвести двойную операцию разыменования
PS Не торопитесь с указателями - читайте главу по несколько раз, экспериментируйте - тема сложная и задержаться на ней стоит подольше.
PS В чём польза укзателей, представьте у вас в памяти сидит DVD-фильм и занимает область в несколько Гигабайт, вам нужно скопировать переменную с DVD-фильмом в функцию обработать и вернуть. Копировать DVD-фильм очень накладно, проще передать указатель на эту область памяти (указатель ничего не занимает, только место в котором хранится адрес переменной) и обращаться к области памяти по указателю.
Или например, разрабатываете вы библиотеку и имеется потребность запускать функции, пользователя библиотеки, т.е. функции, которые ещё не разработаны. Вы можете прибегнуть к указателям, так как они могут указывать и на функции (это тоже область памяти в программе) и запускать функции по указателю. Именно так реализуются все функции обратного вызова.
С указателями можно делать много что полезного, по мере изучения языка вы с этим столкнётесь. | |
|
|
|
|
|
|
|
для: cheops
(30.10.2006 в 12:11)
| | Причём в других языках они тоже непременно присутствуют.
Например, в HTML они скрыты под неприметным понятием "гиперссылка". Если в "избранном" есть ссылка, это ещё не значит, что на компьютере имеется страница по ссылке. Если страница перестаёт существовать, появляется "битая ссылка или "висящий указатель" в терминах C++. В JS все объекты по умолчанию передаются в функцию и в операторы как ссылки (указатели). От этого возникают недоразумения - думают, что работают с копией объекта, а работают с единственным экземпляром. В русском, например, "слон" означает не реальное животное, а ссылку на него. То же - о главах книги, перечисленных в содержании. Все упоминания о главе будут ссылками, кроме одного, имеющегося в заголовке главы.
Так же и в языке программирования, сложные конструкции упоминаются в виде указателей гораздо чаще, чем встречаются в памяти их копии. С указателями проще работать, чем каждый раз при упоминании приводить копию. Тем более, что оригинал, бывает, меняется, и применяя указатель, мы ссылаемся на оригинал в состоянии, имеющемся в данный момент. Копия оригинала будет застывшим слепком, отнесённым к прошедшему времени.
Бывает, что копия тоже нужна, и уметь делать копии в нужный момент и не забывать о версиях оригинала - важная составляющая программирования на любом языке. Особенно ярко непонимание проявляется в момент перехода от "академических" канонических функций к реальным функциям программного проекта. Функции ссылаются на параметры и используют глобальные переменные. С переменными всё ясно - это ссылки на оригиналы. Параметры по канону - это взятые значения, копии. Но в c/c++ имеется способ явно указать, берём мы значения параметров или ссылки. Взять ссылку в качестве параметра - записывается как параметр-указатель. (Сам указатель будет значением, копией адреса памяти, по которому находится оригинал.) Работая с указателем или значением, мы выходим на явный уровень работы с оригиналами или копиями.
Впрочем, имя переменной в выражениях var1 - это уже указатель на данное, но возвращает он данное. И в выражении var1+var2 мы неявно подразумеваем использование ссылок на данное. Если мы захотим вести речь не о данных по адресу переменной (структуры, объекта), а о самом адресе (хотя бы чтобы передать в функцию), возникает необходимость операции "именования" (взятие указателя) &var1, и переходим от упоминания данного, лежащего по ссылке к упоминанию самой ссылки как данного. Т.е. к упоминанию указателя. | |
|
|
|
|
|
|
|
для: 12345
(30.10.2006 в 15:45)
| | Небольшая поправка относительно ссылок в других языках - это не совсем тоже, что указатель в С++, ссылки имеются и в C++ (в С их нет) - ссылка действует тоже как указатель, но для получения результата не требуется разыменовка, ссылка не может быть не корректной - она всегда указывает на реальный объект, указатель может указывать куда угодно в том числе и на несуществующий объект (здесь аналогия с гиперссылкой очень удачна). Нельзя создать ссылку на ссылку, как указатель на указатель. В этом плане ссылки более безопасны, чем указатели, но менее мощны - с их помощью уже нельзя создавать двух-связные списки и осуществлять другие интересные и "хитрые" операции. | |
|
|
|
|
|
|
|
для: cheops
(30.10.2006 в 15:56)
| | И ещё замечание по русскому - "слон" - это имя, или переменная. В зависимости от контекста, оно указывает на реальное животное, его описание в книге, рисунок или синонимы. При использовании берут его значение. А "&слон" соответственно - место, где находится реальный слон или его описание в книге, место рисунка или другого синонима. Если руководителю группы дизайнеров нужно использование копии рисунка, он говорит: "Поставьте слона справа". Если в результате нужна мастер-копия, постоянно меняющаяся другой подгруппой художников, он говорит: "Поставьте &слона справа". Снимается вопрос согласования версий. Правда, такое выражение будет работать, если они используют c/c++. И при этом догадливы, чтобы ставить не координаты мастер-копии на хард-диске сервера, а значение.
Как это, кстати, записать? Мы не можем писать " ", потому что это текущее значение "слон". А значение нам надо брать при компиляции готового проекта. Выходит, что разыменование надо делать на этапе просмотра, а в макете действительно использовать указатель? Макет смещается, таким образом, на один уровень абстракции вверх, потому что включил в себя не объект, а указатель, и для просмотра нужна операция. | |
|
|
|
|