Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programmirovanie_na_S__Ch1_Strukturnoe_i_modul.doc
Скачиваний:
14
Добавлен:
22.02.2015
Размер:
553.98 Кб
Скачать

Операции с указателями

С указателями могут выполняться следующие операции: разадресация, или косвенное обращение к объекту ( * ), присваивание, сложение с константой, вычитание, инкремент (++), декремент (--), сравнение, приведение типов. При работе с указателями часто используется операция получения адреса (&).

Операция разадресации, или разыменования, предназначена для доступа к величине, адрес которой хранится в указателе:

char a;

char *p = new char;

*p = 'A'; a = *p;

unsigned long int A = 147483647;

unsigned short int *pi = (unsigned short int*)&A;

В последней строке происходит явное приведение типов.

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

Ссылки

Ссылка представляет собой синоним имени, указанного при инициализации ссылки. Ссылки можно рассматривать как указатель, который всегда разыменовывается. Формат объявления ссылки: тип & имя;

где тип − это тип величины, на которую указывает ссылка; & − оператор ссылки, указывающий, что следующее за ним имя является именем переменной ссылочного типа.

Примеры

int kol;

int & pal = kol; // ссылка pal − альтернативное имя kol

const char & cr = '\n'; // ссылка на константу

При работе со ссылками следует выполнять следующие правила:

1. Переменная-ссылка должна явно инициализироваться при ее описании.

2. После инициализации ссылке не может быть присвоено имя другой переменной.

3. Тип ссылки должен совпадать с типом величины, на которую он ссылается.

4. Не разрешается определять указатели на ссылки, создавать массивы ссылок и ссылки на ссылки.

Ссылки чаще всего применяются в качестве параметров функций и типов возвращаемых функциями значений (см. методические указания «Программирование на языке С++. Часть 2. Модульное программирование»).

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

Массивы Одномерные массивы

Конечная именованная последовательность однотипных величин называется массивом. Описание массива в С++ выглядит следующим образом: имя, после которого в квадратных скобках задается количество элементов массива, например,

float a[10];

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

int b[5] = {3, 2, 1} // элементы b[3] и b[4] обнуляются

Размерность массивов предпочтительнее задавать с помощью именованных констант:

const int n = 5;

int marks[n]={4, 4, 5, 3, 4};

Динамические массивы

Динамические массивы создаются с помощью операции new, при этом необходимо указать тип и размерность, например:

int n = 100;

float *p = new float [n];

В этом примере создается переменная-указатель на float, в динамической памяти отводится непрерывная область, достаточная для размещения 100 чисел вещественного типа, и адрес ее начала записывается в указатель p. Динамические массивы нельзя при создании инициализировать, и они не обнуляются.

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

p[5] или через указатель *(p+5).

Альтернативный способ создания динамического массива − использование функции malloc библиотеки С:

int n =100;

float *q = (float*)malloc(n*sizeof(float));

Память, зарезервированная под динамический массив с помощью new [ ], должна освобождаться с помощью оператора delete [ ], а память, выделенная с помощью функции malloc, − посредством функции free:

delete [ ] p;

free (q);

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

Инкремент перемещает указатель к следующему элементу массива, декремент − к предыдущему. Фактически значение указателя изменяется на величину sizeof (тип). Если указатель на определенный тип увеличивается или уменьшается на константу, его значение изменяется на величину этой константы, умноженной на размер объекта данного типа, например:

short int *p = new short [5];

p++; // значение p увеличивается на 2 (байта)

long *q = new long [5];

q++; // значение q увеличивается на 4 (байта)

Выражение (*p)++ инкрементирует значение, на которое ссылается указатель.

При записи выражения с указателями следует обращать внимание на приоритет операций. Рассмотрим такой пример:

*p++ = 10;

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

*p = 10; p ++;

Задания

  1. Написать программу, вычисляющую сумму элементов числового массива из 10 элементов и их среднее арифметическое.

  2. Написать программу, находящую максимальный и минимальный элементы числового массива (размерность массива задает пользователь).

  3. Написать программу, сортирующую элементы числового массива в порядке возрастания их значений (размерность массива задает пользователь).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]