Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Разъясните мне простым языком, что такое указатели в c++ и где их удобно применять?
 
 автор: 123php   (30.10.2006 в 11:51)   письмо автору
 
 

Разъясните мне простым языком, что такое указатели в c++ и где их удобно применять?

   
 
 автор: cheops   (30.10.2006 в 12:11)   письмо автору
 
   для: 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 = &prt;

В этом случае p - будет двойным указателем, который обычно объявляется следующим образом
int **p = &prt;

Получить значение к переменной var по двойному указателю можно, если произвести двойную операцию разыменования
cout << **p << "\n";

PS Не торопитесь с указателями - читайте главу по несколько раз, экспериментируйте - тема сложная и задержаться на ней стоит подольше.

PS В чём польза укзателей, представьте у вас в памяти сидит DVD-фильм и занимает область в несколько Гигабайт, вам нужно скопировать переменную с DVD-фильмом в функцию обработать и вернуть. Копировать DVD-фильм очень накладно, проще передать указатель на эту область памяти (указатель ничего не занимает, только место в котором хранится адрес переменной) и обращаться к области памяти по указателю.
Или например, разрабатываете вы библиотеку и имеется потребность запускать функции, пользователя библиотеки, т.е. функции, которые ещё не разработаны. Вы можете прибегнуть к указателям, так как они могут указывать и на функции (это тоже область памяти в программе) и запускать функции по указателю. Именно так реализуются все функции обратного вызова.
С указателями можно делать много что полезного, по мере изучения языка вы с этим столкнётесь.

   
 
 автор: 12345   (30.10.2006 в 15:45)   письмо автору
 
   для: cheops   (30.10.2006 в 12:11)
 

Причём в других языках они тоже непременно присутствуют.
Например, в HTML они скрыты под неприметным понятием "гиперссылка". Если в "избранном" есть ссылка, это ещё не значит, что на компьютере имеется страница по ссылке. Если страница перестаёт существовать, появляется "битая ссылка или "висящий указатель" в терминах C++. В JS все объекты по умолчанию передаются в функцию и в операторы как ссылки (указатели). От этого возникают недоразумения - думают, что работают с копией объекта, а работают с единственным экземпляром. В русском, например, "слон" означает не реальное животное, а ссылку на него. То же - о главах книги, перечисленных в содержании. Все упоминания о главе будут ссылками, кроме одного, имеющегося в заголовке главы.

Так же и в языке программирования, сложные конструкции упоминаются в виде указателей гораздо чаще, чем встречаются в памяти их копии. С указателями проще работать, чем каждый раз при упоминании приводить копию. Тем более, что оригинал, бывает, меняется, и применяя указатель, мы ссылаемся на оригинал в состоянии, имеющемся в данный момент. Копия оригинала будет застывшим слепком, отнесённым к прошедшему времени.

Бывает, что копия тоже нужна, и уметь делать копии в нужный момент и не забывать о версиях оригинала - важная составляющая программирования на любом языке. Особенно ярко непонимание проявляется в момент перехода от "академических" канонических функций к реальным функциям программного проекта. Функции ссылаются на параметры и используют глобальные переменные. С переменными всё ясно - это ссылки на оригиналы. Параметры по канону - это взятые значения, копии. Но в c/c++ имеется способ явно указать, берём мы значения параметров или ссылки. Взять ссылку в качестве параметра - записывается как параметр-указатель. (Сам указатель будет значением, копией адреса памяти, по которому находится оригинал.) Работая с указателем или значением, мы выходим на явный уровень работы с оригиналами или копиями.

Впрочем, имя переменной в выражениях var1 - это уже указатель на данное, но возвращает он данное. И в выражении var1+var2 мы неявно подразумеваем использование ссылок на данное. Если мы захотим вести речь не о данных по адресу переменной (структуры, объекта), а о самом адресе (хотя бы чтобы передать в функцию), возникает необходимость операции "именования" (взятие указателя) &var1, и переходим от упоминания данного, лежащего по ссылке к упоминанию самой ссылки как данного. Т.е. к упоминанию указателя.

   
 
 автор: cheops   (30.10.2006 в 15:56)   письмо автору
 
   для: 12345   (30.10.2006 в 15:45)
 

Небольшая поправка относительно ссылок в других языках - это не совсем тоже, что указатель в С++, ссылки имеются и в C++ (в С их нет) - ссылка действует тоже как указатель, но для получения результата не требуется разыменовка, ссылка не может быть не корректной - она всегда указывает на реальный объект, указатель может указывать куда угодно в том числе и на несуществующий объект (здесь аналогия с гиперссылкой очень удачна). Нельзя создать ссылку на ссылку, как указатель на указатель. В этом плане ссылки более безопасны, чем указатели, но менее мощны - с их помощью уже нельзя создавать двух-связные списки и осуществлять другие интересные и "хитрые" операции.

   
 
 автор: 12345   (30.10.2006 в 16:49)   письмо автору
 
   для: cheops   (30.10.2006 в 15:56)
 

И ещё замечание по русскому - "слон" - это имя, или переменная. В зависимости от контекста, оно указывает на реальное животное, его описание в книге, рисунок или синонимы. При использовании берут его значение. А "&слон" соответственно - место, где находится реальный слон или его описание в книге, место рисунка или другого синонима. Если руководителю группы дизайнеров нужно использование копии рисунка, он говорит: "Поставьте слона справа". Если в результате нужна мастер-копия, постоянно меняющаяся другой подгруппой художников, он говорит: "Поставьте &слона справа". Снимается вопрос согласования версий. Правда, такое выражение будет работать, если они используют c/c++. И при этом догадливы, чтобы ставить не координаты мастер-копии на хард-диске сервера, а значение.

Как это, кстати, записать? Мы не можем писать "
*&слона
", потому что это текущее значение "слон". А значение нам надо брать при компиляции готового проекта. Выходит, что разыменование надо делать на этапе просмотра, а в макете действительно использовать указатель? Макет смещается, таким образом, на один уровень абстракции вверх, потому что включил в себя не объект, а указатель, и для просмотра нужна операция.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования