Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Примеры объявления указателей




Указатель может быть константой или переменной, а также указывать на константу или переменную. Рассмотрим примеры:

int i; // целая переменная
const int ci = 1; // целая константа
int * pi; // указатель на целую переменную
const int * pci; // указатель на целую константу
int * const ср = &i; // указатель-константа на целую переменную
const int * const срс = &ci; // указатель-константа на целую константу

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

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

Инициализация указателей

Указатели чаще всего используют при работе с динамической памятью, называемой некоторыми эстетами кучей (перевод с английского языка слова heap). Это свободная память, в которой можно во время выполнения программы выделять место в соответствии с потребностями. Доступ к выделенным участкам динамической памяти, называемым динамическими переменными, производится только через указатели. Время жизни динамических переменных — от точки создания до конца программы или до явного освобождения памяти. В C++ используется два способа работы с динамической памятью. Первый использует семейство функций malloc и достался в наследство от С, второй использует операции new и delete.

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

Способы инициализации указателей

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

o с помощью операции получения адреса:
int а = 5; // целая переменная
int* р = &а; //в указатель записывается адрес а
int* р (&а); // то же самое другим способом

o с помощью значения другого инициализированного указателя:
int* r = р;

o с помощью имени массива или функции, которые трактуются как адрес:
int b[10]; // массив
int* t = b; // присваивание адреса начала массива
...
void f(int а){ /*... * / } // определение функции
void (*pf)(int); // указатель на функцию
pf = f; // присваивание адреса функции

2. Присваивание указателю адреса области памяти в явном виде:
char* vp = (char *)0хВ8000000;
Здесь 0хВ8000000 — шестнадцатеричная константа, (char *) — операция приведения типа: константа преобразуется к типу «указатель на char».

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

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

o с помощью операции new:
int* n = new int; //1
int* m = new int (10); // 2
int* q = new int [10]; // 3

o с помощью функции malloc (для того чтобы использовать malloc, требуется подключить к программе заголовочный файл <malloc.h>.)
int* u = (int *)malloc(s1zeof(int)); // 4

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

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

Синтаксис перечисления. Синтаксис объединения. Особенности размещения в памяти и доступности. Элементы перечисления.

Перечисления (enum)

Перечисления - это ещё один пользовательский тип данных. Перечисления используют для описания какого-то небольшого множества значений.

С помощью перечислений можно задать дни недели, месяцы, ну или что-нибудь подобное. В качестве примера рассмотрим стороны света. Стороны света на экране расположены так: вверху - север (north), справа - восток (east), слева - запад (west) и внизу - юг (south).

enum cardinal_dirs { north, west, east, south };

Здесь мы определили перечисление cardinal_dirs. В начале строки стоит ключевое слово enum (enum eration - перечисление). Затем указывается имя перечисления, после которого, через пробел, в фигурных скобках задаются значения, которые смогут принимать переменные типа cardinal_dirs. После фигурных скобок ставится точка с запятой.

После того, как определено перечисление, можно создавать переменные нового типа:

cardinal_dirs ch = north;

Обратите внимание, что переменные типа cardinal_dirs могут принимать только четыре значения: north, south, east, west. Кроме того, элементы в перечислении нумеруются от нуля. Т.е. north = 0, east = 1, south = 2, west = 3. Вместо перечисления мы могли бы создать четыре константы:

const int north = 0;

const int east = 1;

const int south = 2;

const int west = 3;

использовать перечисления довольно легко. Но стороны света у нас закодированы клавишами стрелочек, поэтому нам нужно инициализировать элементы перечисления числами. Как я уже писал, отсчёт ведётся с нуля. Но, к счастью, это можно изменить. Если мы переопределим какой-либо элемент значением 75, то следующий, получит значение 76. Нам нужно переопределить все четыре значения.

enum cardinal_dirs { north = 72, west = 75, east = 77, south = 80 };

Объединения

Объединение - это формат данных, который может содержать различные типы данных, но только один тип одновременно. Объединение позволяет нескольким переменным различных типов занимать один участок памяти (т. е. все переменные-члены объединения имеют одинаковый адрес). Синтаксис объединения следующий: union [имя_объединения] {список_переменных} [имя_объекта]; Приведем пример объединения: union Num{ int int_var; double double_var; }; Размер, который занимает в памяти объединение, равен размеру наибольшего элемента данного объединения. То есть, когда мы создаем объединение, компилятор выделяет память под объединение размером с наибольший элемент объединения.

Существует два способа объявления объекта объединения. В языке С объект объявляется следующим образом:

union имя_объединения имя_объекта;

В С++ не обязательно использовать ключевое слово union, то есть объект объединения можно объявить следующим образом:

имя_объединения имя_объекта;

пример работы с объединением:

#include <iostream.h> union Num{ int int_var; double double_var; }; void main(){ Num obj; obj.int_var = 5; cout<<obj.int_var<<endl; obj.double_var = 12; cout<<obj.double_var<<endl; cout<<obj.int_var<<endl; }выведет на экран 5 12 0 //результат будет неоднозначным, //т.к. в данный момент времени существует только double_var

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

void main(){ union { int i; char ch; }; i = 5; cout<<i<<endl; ch = 's'; cout<<ch<<endl;}на экране отобразится: 5

8) Определение функции. Передача аргументов и возврат значения по значению. Ссылки и указатель. Аргументы по умолчанию. Константы аргументов функции.

В C++ код, описывающий, что делает функция, называется определением функции (function definition). Формально это выглядит так:

заголовок_функции { инструкции }

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

Заголовок функции — это:

тип имя(список_объявлений_параметров)

Спецификация типа, стоящая перед именем функции, является возвращаемым ти­пом. Он определяет тип значения, возвращаемого функцией (если оно вообще воз­вращается), если функция ничего не возвращается то необходимо указать ее тип как void.

Пример:void Say() { cout<<”Hello, world!”; }

Аргументы функции

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

/* Возвращает 1, если символ c входит в строку s; и 0 в противном случае. */int is_in(char *s, char c){ while(*s) if(*s==c) return 1; else s++; return 0;}
Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...