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

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

Инициализация. При определении указателя надо стремиться выполнить его инициализации, т.е





При определении указателя надо стремиться выполнить его инициализации, т.е. присвоение начального значения. Непреднамеренное использование неинициализированных указателей – распространенный источник ошибок в программе. Инициализатор записывается после имени указателя либо в круглых скобках, либо после знака равенства.

Существуют следующие способы инициализации указателей:

1. Присваивание указателю адреса существующего объекта:

· с помощью операции получения адреса:

int a = 5; //целая переменная

int* p = &a; //в указатель записывается адрес а

int* p (&a); //то же самое другим способом

· с помощью значения другого инициализированного указателя

int* r = p;

· с помощью имени массива или функции, которые трактуются как адрес

int b[10]; //массив

int* t = b; //присваивание адреса начала массива

void f(int a){/*….*/}; //определение функции

void (*pf) (int); //указатель на функцию

pf = f; //присваивание адреса функции

2. Присваивание указателю адреса области памяти в явном виде:

char* vp = (char*)0xB8000000;

Здесь 0xB8000000 – шестнадцатеричная константа, (char*) операция приведения типа: константа преобразуется к типу «указатель на char».

3. Присваивание пустого значения:

int* suxx = NULL;

int* rulez = 0;

4. Выделение участка динамической памяти и присваивание ее адреса указателю:

· с помощью операции new:

int* n = new int; //1

int* m = new int (10); //2

int* q = new int [10]; //3

· с помощью операции malloc:

int* u = (int *)malloc(sixeof(int)); //4

 

В первой строчке используется константа NULL, определенная в некоторых заголовочных файлах С, как указатель равный нулю. Рекомендуется использовать просто 0, так как это значение типа int будет правильно преобразовано стандартными способами в соответствии с контекстом. Поскольку гарантируется, что объектов с нулевым адресом нет, пустой указатель можно использовать дл проверки, ссылается указатель на конкретный объект или нет.

В операторе 1 операция new выполняет выделение достаточного для размещения величины типа int участка динамической памяти и записывает адрес начала этого участка в переменную n. Память под саму переменную n (размера, достаточного для размещения указателя) выделяется на этапе компиляции.

В операторе 2, кроме описанных выше действий, производится инициализация выделенной памяти значением 1.

В операторе 3 операция new выполняет выделение памяти под 10 величин типа int (массива из 10 элементов) и записывает адрес начала этого участка в переменную q, которая может трактоваться как имя массива. Через имя можно обращаться к любому элементу массива.

Если память выделить не удалось, по стандарту должно порождаться исключение bad_alloc, старые версии компилятора могут возвращать 0.

В операторе 4 делается то же самое, что и в операторе 1, но с помощью операции выделения памяти malloc, унаследованной из библиотеки С. В функцию передается один параметр – количество выделяемой памяти в байтах. Конструкция (int *) используется для приведения типа указателя, возвращаемого функцией, к требуемому типу. Если память выделить не удалось, то функция возвращает 0.

Операцию new использовать предпочтительнее, чем malloc, особенно при работе с объектами.

Освобождение памяти, выделенной с помощью операции new, должно производиться с помощью delete, а памяти, выделенной функцией malloc – посредством функции free. При этом переменная-указатель сохраняется и может инициализироваться повторно. Приведенные выше динамические переменные уничтожаются следующим образом:

delete n; delete m; delete [] q; free (u);

Если память выделялась с помощью new[], для освобождения памяти необходимо применять delete []. Размерность массива при этом не указывается. Если квадратных скобок нет, то никакого сообщения об ошибке не выдается, но помечен как свободный будет только первый элемент массива, а остальные окажутся недоступны для дальнейших операций. Такие ячейки памяти называются мусором.

Если переменная-указатель выходит из области своего действия, отведенная под нее память освобождается. Следовательно, динамическая переменная, на которую ссылается указатель, становится недоступной. При этом память из-под самой динамической переменной не освобождается. Другой случай появления «мусора» – когда инициализированному указателю присваивается значение другого указателя. При этом старое значение бесследно теряется.

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

int *(*p[10])();

объявляется массив из 10 указателей на функции без параметров, возвращающих указатели на int.

По умолчанию квадратные и круглые скобки имеют одинаковый приоритет, больший, чем звездочка, и рассматриваются слева направо. Для изменения порядка рассмотрения используются круглые скобки.

При интерпретации сложных описаний необходимо придерживаться правила «изнутри наружу»:

· если справа от имени имеются квадратные скобки, это массив, если скобки круглые – функция;

· если слева есть звездочка, это указатель на проинтерпретированную ранее конструкцию;

· если справа встречается закрывающая круглая скобка, необходимо применить переменные выше правила внутри скобок, а затем переходить наружу;

· в последнюю очередь интерпретируется спецификатор типа.

Для приведенного выше описания порядок интерпретации указан цифрами:

int *(*p[10])();







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




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


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


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


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

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

Этапы трансляции и их характеристика Трансляция (от лат. translatio — перевод) — процесс синтеза белка из аминокислот на матрице информационной (матричной) РНК (иРНК...

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

Решение Постоянные издержки (FC) не зависят от изменения объёма производства, существуют постоянно...

ТРАНСПОРТНАЯ ИММОБИЛИЗАЦИЯ   Под транспортной иммобилизацией понимают мероприятия, направленные на обеспечение покоя в поврежденном участке тела и близлежащих к нему суставах на период перевозки пострадавшего в лечебное учреждение...

Кишечный шов (Ламбера, Альберта, Шмидена, Матешука) Кишечный шов– это способ соединения кишечной стенки. В основе кишечного шва лежит принцип футлярного строения кишечной стенки...

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