Инициализация указателей
При декларации указателя желательно выполнить его инициализацию, т.е. присвоение начального значения. Наиболее распространенная из ошибок в программах – непреднамеренное использование неинициализированных указателей.
Инициализатор записывается после ID указателя либо в круглых скобках, либо после знака равенства.
Существуют следующие способы инициализации указателя:
1. Присваивание указателю адреса существующего объекта:
а) используя операцию получения адреса переменной:
int a = 5;
int *p = &а; – указателю p присвоили адрес объекта а;
int *p(&а); – то же самое другим способом;
б) с помощью значения другого инициализированного указателя:
int *g = р;
Указателю-переменной можно присвоить значение другого указателя либо выражения типа указатель с использованием при необходимости операции приведения типа. Приведение типа необязательно, если один из указателей имеет тип void *, например
int i,*x;
char *y;
x = &i; // x – поле объекта int;
y = (char *)x; // y – поле объекта char;
y = (char *)&i; // y – поле объекта char;
в) с помощью идентификаторов массива или функции, которые трактуются как адрес начала участка памяти, в котором размещается указанный объект. Причем следует учитывать тот факт, что ID массивов и функций являются константными указателями. Такую константу можно присвоить переменной типа указатель, но нельзя подвергать преобразованиям, например:
int x[100], *y;
y = x; – присваивание константы переменной;
x = y; – ошибка, т.к. в левой части указатель-константа.
2. Присваивание пустого значения:
int *x1 = NULL;
int *x2 = 0;
В первой строке используется константа NULL, определенная как указатель, равный нулю. Рекомендуется использовать просто цифру 0, так как это значение типа int будет правильно преобразовано стандартными способами в соответствии с контекстом. А так как объекта с нулевым (фиктивным) адресом не существует, пустой указатель обычно используют для контроля, ссылается указатель на конкретный объект или нет.
3. Присваивание указателю адреса выделенного участка динамической памяти:
а) c помощью операции new (см. разд. 16.4):
int *n = new int;
int *m = new int (10);
б) c помощью функции malloc (см. разд. 10.9):
int *p = (int*)malloc(sizeof(int));
Присваивание без явного приведения типов допускается в двух случаях:
– указателям типа void*;
– если тип указателей справа и слева от операции присваивания один и тот же.
Если переменная-указатель выходит из области своего действия, отведенная под нее память освобождается. Следовательно, динамическая переменная, на которую ссылался указатель, становится недоступной. При этом память, на которую указывала сама динамическая переменная, не освобождается. Такая ситуация называется «замусоривание оперативной памяти». Еще одна причина появления «мусора» – когда инициализированному указателю присваивается значение другого указателя. При этом старое значение указателя теряется.
Дата добавления: 2017-10-04; просмотров: 1063;