|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
УказателиУказатель - это переменная, содержащая адрес области памяти. Указатели широко применяются в языке С++. В некоторых случаях без них просто не обойтись, а в некоторых программы с использованием указателей становятся короче и эффективнее. Начнем с того, что поговорим о структуре памяти любого компьютера. Как известно, память компьютера представляет последовательность 8-битовых байтов. Каждый байт пронумерован, причем нумерация начинается с нуля. Номер байта называется адресом. Иногда говорят, что адрес указывает на определенный байт. Таким образом, указатель является просто адресом байта памяти. Язык С++ позволяет определять переменные, которые могут хранить адреса памяти. Такие переменные и называются указателями. Значение указателя сообщает о том, где размещен объект, но ничего не говорит о значении самого объекта.
Присваивая указателю то или иное допустимое значение, можно обеспечить доступ к данным через этот указатель. Для описания переменной типа указатель используется символ *.
Формат описания: Тип *имя; Указатель – адрес переменной какого-то определенного типа. Этот тип сообщается компилятору при объявлении указателя. int *x; char *y; Пример следует понимать так: x – это указатель на ячейку, в которой хранится целое значение, а y – указатель на однобайтовую ячейку, предназначенную для хранения символа. Двумя наиболее важными операциями, связанными с указателями, являются операция обращения по адресу * и определение адреса &. Операция обращения по адресу предназначена для записи или считывания значения, размещенного по адресу, содержащемуся в переменной-указателе. Например: int *x; //объявление указателя х ... *x=5; //запись по адресу х значения 5 Операция определения адреса & возвращает адрес памяти своего операнда. Операндом должна быть переменная. Например: int *x; // объявление указателя х int a=5; //объявление и инициализация переменной а x=&a; //копирование адреса переменной а в х
Кроме того, над указателями можно выполнять арифметические операции сложения и вычитания. Если у – указатель на целое, то унарная операция y++ увеличивает значение адреса, хранящегося в переменной-указателе на число равное размеру ячейки целого типа, т.е. на 2 байта для 16-разрядного процессора и на 4 байта – для 32-разрядного; теперь оно является адресом следующей ячейки целого типа. Соответственно, оператор y--; означает, что адрес уменьшается аналогично на 2 или на 4 байта. Указатели и целые числа можно складывать. Конструкция у + n (у - указатель, n - целое число) задает адрес n-гo объекта, на который указывает у. Это справедливо для любых объектов (int, char, float и др.); транслятор будет масштабировать приращение адреса в соответствии с типом, указанным в определении объекта. Любой адрес можно проверить на равенство (==) или неравенство (!=), больше (>) или меньше (<) с любым другим адресом. Рассмотрим следующий фрагмент программы:
#include "stdafx.h" int main() { int *x, *w; int y; *x=18; y=-15; w=&y; ... } Этот текст можно понимать так: Выделить память под три переменные x, w, y, где x и w –переменные типа указатель. Оператор *x=18; означает, что в ячейку, адрес которой записан в x, помещается значение 18. Затем переменной y присваивается значение -15. После чего в указатель w записывается адрес переменной y. Синтаксически текст записан правильно. Проблема заключается в том, что указатель x не инициализирован. Описание int *x; это лишь указание компилятору резервировать память, необходимую для хранения адреса целой ячейки. Но в этой памяти может оказаться адрес любой ячейки, в том числе и адрес, где хранится полезная информация, например, операционная система. Запись в такую ячейку может привести к сбою в работе компьютера. Поэтому при работе с указателями их надо правильно инициализировать. Существует 4 способа правильного задания начального значения для указателя: 1) Описать указатель глобально, т.е. вне любой функции. При этом указатель будет инициализирован безопасным нулевым адресом. Кроме того любому указателю можно присвоить безопасный нулевой адрес, например: int *x; x=NULL; Гарантируется, что этот адрес не совпадет ни с одним адресом, уже использованным в системе. 2) Присвоить указателю адрес переменной. Например: w=&y; 3) Присвоить указателю значение другого указателя, к этому моменту правильно инициализированного. Например: x=w; 4 ) Использовать функции выделения динамической памяти malloc() или calloc(). При использовании этих функция необходимо подключать библиотеку <malloc.h>. Рассмотрим пример использования функции malloc(): x=(int*)malloc(sizeof(int)); Приведенный пример означает, что функция выделит область памяти, размер которой определит функция sizeof(). Если вы знаете, что размер ячейки типа int равен 2 байтам, то можно написать проще: x=(int*)malloc(2); По окончанию работы программы, память, выделенную функцией malloc() рекомендуется освободить функцией free(x); Вернемся к приведенному ранее фрагменту программы: #include "stdafx.h" #include <malloc.h>
int main() { int *x, *w; int y; x=(int*)malloc(sizeof(int)); *x=16; y=-15; w=&y; ... } Теперь никаких конфликтных ситуаций при работе с указателями не возникнет. В языке С++ существует еще одна пара операторов new и delete для динамического выделения и освобождения памяти. О них мы поговорим чуть позже. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.008 сек.) |