Студопедия — Объявление, инициализация и использование указателей
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Объявление, инициализация и использование указателей






Тема 4 Указатели и ссылки

 

Все языки программирования используют указатели. Однако некоторые языки используют их «скрытно», т.е. они недоступны программистам.

На заре программирования программисты управляли данными в памяти компьютера, непосредственно определяя адрес памяти, содержащий данные. Можно легко представить, что непосредственная манипуляция памятью была делом чрезвычайно сложным. Поэтому сообщество разработчиков программного обеспечения приняло решение разработать языки программирования, в которых будут использоваться имена для ячеек памяти (или переменные), а компилятор или интерпретатор будут «заботиться» об отображении имен переменных в их адреса памяти. Фактически, особенность программирования, которую мы рассматриваем сейчас как нечто само собой разумеющееся, забрала из рук программиста возможность «хозяйничать» в памяти (довольно деликатное дело). Но в языке С++ такая возможность программисту легко доступна благодаря указателям.

 

Объявление, инициализация и использование указателей

Итак, имя переменной ассоциируется с ее адресом и типом данных. Эта связь позволяет компилятору или интерпретатору, по существу, иметь доступ к памяти компьютера и интерпретировать данные. Кроме того, имя функции связано с адресом, по которому компилятор или интерпретатор располагает загрузочный код функции.

Указатель – это специальная переменная, в которой хранится адрес другой переменной или объекта.

Знание адреса переменной позволяет получать доступ к данным в такой переменной через указатель. Для правильной интерпретации значения переменной указатель должен имеет тип, соответствующий типу этих данных. Иными словами, тип указателя должен совпадать с типом переменной, на которую он указывает.

Прежде чем использовать указатель, его нужно объявить, как и обычную переменную. Общий синтаксис для объявления указателя:

 

Тип * ИмяУказателя;

 

Тип * ИмяУказателя; // РЕКОМЕНДУЕТСЯ!

 

Символ * можно размещать одним из двух способов – либо сразу после типа указателя, либо сразу перед именем указателя.

При объявлении нескольких указателей символ * должен быть перед именем каждого указателя, например:

 

int *pX, *pY; // улучшает читабельность программы

 

А в этом примере: int* pX, pY; объявлен указатель pX на тип int и обычная целочисленная переменная с именем pY.

В качестве типа указателя можно использовать также тип void*, что обеспечивает доступ к данным любого типа. Чаще всего этот такой тип используется, когда указатель является параметром функции. При этом для того чтобы получить доступ к этим данным, необходимо преобразовать тип указателя к соответствующему типу данных, отличному от void. Кроме того, С++ не поддерживает арифметику с указателями void*, поскольку размер данных не указан. Таким образом, с одной стороны указатели типа void* – это расширение возможностей использования указателей (функции становятся более универсальными), а с другой – это ограничение возможностей использования арифметики указателей.

 

ЗАМЕЧАНИЕ. Поскольку указатели хранят адреса ячеек памяти компьютера, нужно обязательно правильно инициализировать указатели, прежде чем использовать их. Необходимо строго соблюдать это правило во избежание серьёзных проблем с компьютером!

 

Если присвоить указателю нулевой адрес:

 

pX = 0; // или pX = NULL;

 

то он никуда конкретно не указывает. Необходимо явно устанавливать указатели в нулевые адреса, прежде чем сравнивать их адреса с нулем. Некоторые функции, такие как оператор new,который выделяет динамическую память, возвращают нулевые адреса, если они завершают свои операции с указателями аварийно.

Указатели могут быть установлены на существующие переменные. Общий синтаксис для объявления указателя и инициализации его адресом переменной:

 

Тип * ИмяУказателя = & ИмяПеременой;

 

Рассмотрим следующий пример:

 

int A = 18;

// 1-й способ: объявление и инициализация указателя

int *pA = &A; // int *pA = A; неправильно!

// 2-й способ: отдельное объявление и отдельная инициализация указателя

int *pA;

pA = &A;

 

 

Как только адрес существующей переменной присвоен указателю, можно получить доступ к значению этой переменной. Для доступа к значению переменной через указатель используется операция разыменования (разадресации) указателя:

 

* ИмяУказателя

Она дает значение по адресу. Примеры:

 

int A = 18, B = 36;

 

int *pA = &A;

 

printf(“A = %d”, *pA); // будет напечатано 18

 

*pA = 45;

 

printf(“A = %d”, A); // будет напечатано 45

 

Примеры правильного и неправильного использования указателей:

 

*pA = A; или *pA = 10; // значение = значение

 

pA = &A; // указатель = адрес (присвоить указателю адрес)

 

pA = A; или pA = 10; // ОШИБКА! указатель = значение

 

*pA = &A; // ОШИБКА! значение = указатель

 

ЗАМЕЧАНИЕ. Нет никакой необходимости использовать указатель на переменную, если известно имя переменной. Поэтому указатели в основном используются для передачи параметров функциям и для работы с динамической памятью компьютера.

 

Ссылки

 

Ссылки появились в языке С++ позднее, чтобы упростить работу с указателями. По сути, ссылка – это тоже указатель, только неявный. Ссылка – это псевдоним (второе имя) существующей переменной. Работа со ссылкой похожа на работу с обычной переменной. Общий синтаксис для объявления ссылки:

 

Тип &; ИмяСсылки = ИмяПеременной;

 

Тип &;ИмяСсылки = ИмяПеременной; // РЕКОМЕНДУЕТСЯ!

 

Знак & в данном случае не означает операцию взятия адреса. Если он используется при объявлении переменной, то это означает объявление переменной-ссылки.

Ссылка должна обязательно инициализироваться при объявлении. Нельзя объявить ссылку, не указав, на какую переменную она ссылается.

Исключением является ссылка, используемая в качестве параметра функции. Параметр-ссылка может быть просто объявлен, а его инициализация произойдет в момент вызова функции.

В следующем примере объявлены переменные A и B типа int, а также ссылка pA на переменную A. Это означает, что у переменной A появилось второе имя pA, и теперь можно обращаться к одной и той же переменной, используя любое из этих имен. Ссылке pA присваивается значение 10, а затем печатается значение переменной A, которое также будет равно 10.

Однако нельзя впоследствии установить ту же ссылку pA на другую переменную B. Это объясняется тем, что ссылка не занимает места в памяти, поэтому она не может изменять свое значение в процессе работы в отличие от обычных переменных и переменных-указателей, которые занимают место в памяти.

 

int A, B;

int &pA = A;

A = 10;

printf(“pA = %d”, pA); // будет напечатано pA = 10

 

pA = 20;

 

printf(“A = %d”, A); // будет напечатано A = 20

 

pA = B; // ОШИБКА!

 

 

Ссылки значительно упростили работу с указателями. Они не требуют использования операции разадресации (или разыменования) указателя * для того, чтобы получить значение по указанному адресу.

ЗАМЕЧАНИЕ. Разумеется, нет никакой необходимости в использовании нескольких имен для одной и той же переменной. Поэтому основное назначение ссылок – это передача параметров функциям.

 







Дата добавления: 2015-08-12; просмотров: 844. Нарушение авторских прав; Мы поможем в написании вашей работы!



Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Теория усилителей. Схема Основная масса современных аналоговых и аналого-цифровых электронных устройств выполняется на специализированных микросхемах...

Медицинская документация родильного дома Учетные формы родильного дома № 111/у Индивидуальная карта беременной и родильницы № 113/у Обменная карта родильного дома...

Основные разделы работы участкового врача-педиатра Ведущей фигурой в организации внебольничной помощи детям является участковый врач-педиатр детской городской поликлиники...

Ученые, внесшие большой вклад в развитие науки биологии Краткая история развития биологии. Чарльз Дарвин (1809 -1882)- основной труд « О происхождении видов путем естественного отбора или Сохранение благоприятствующих пород в борьбе за жизнь»...

Упражнение Джеффа. Это список вопросов или утверждений, отвечая на которые участник может раскрыть свой внутренний мир перед другими участниками и узнать о других участниках больше...

Влияние первой русской революции 1905-1907 гг. на Казахстан. Революция в России (1905-1907 гг.), дала первый толчок политическому пробуждению трудящихся Казахстана, развитию национально-освободительного рабочего движения против гнета. В Казахстане, находившемся далеко от политических центров Российской империи...

Виды сухожильных швов После выделения культи сухожилия и эвакуации гематомы приступают к восстановлению целостности сухожилия...

Studopedia.info - Студопедия - 2014-2024 год . (0.01 сек.) русская версия | украинская версия