Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tekhnologia_programmirovania.pdf
Скачиваний:
182
Добавлен:
08.04.2015
Размер:
1.76 Mб
Скачать

118

Глава 10. Указатели и ссылки

10.1.Указатели и адреса

Вязыке C++ можно определять переменные, значениями которых являются адреса других переменных. Такие переменные называются указателями. Для объявления указателя после имени типа ставится *,

например,

char *p;

// p – указатель на переменную типа char

Существует унарный оператор &, выдающий адрес своего операнда. После выполнения инструкций:

char c = ’0’; p = &c;

указатель p будет содержать адрес переменной c (говорят, что p ссылается на c). Схема расположения в памяти переменной c и указателя p, содержащего ее адрес, показана на рис.34. Символьная переменная c занимает один байт памяти, а указатель p – четыре. Такое количество памяти выделяется под указатели на 32 –разрядных компьютерах, в которых для формирования адресов используется 4 байта, состоящих из 8 двоичных разрядов – битов.

··

 

p

с

 

··

·

 

 

 

 

···

 

 

 

 

 

 

 

 

 

 

 

 

·

Рис.35. Связь объекта и указателя на него

 

 

 

 

 

 

К указателю можно применять унарный оператор *, возвращаюший объект, на который ссылается данный указатель, например,

*p = ’A’;

// Теперь c = ’A’

Иначе говоря, если p указывает на c, то *p и c – это одно и то же. Можно создавать указатели на величины любых типов.

Программа 25. Расчет треугольника

Пусть требуется вычислить периметр и площадь треугольника по трем его сторонам a, b, c. Напишем для этого функцию triangle. Так как треугольник существует не для любых значений длин сторон, функция должна как-то информировать об этом. Пусть она будет возвращать 1,

Указатели и ссылки 119

если для заданных длин сторон треугольник существует, и 0, если не существует. Две остальные величины – периметр и площадь – будем возвращать из функции через аргументы, другого способа нет, но чтобы сформировать значения аргументов внутри функции, туда будем передавать их адреса.

Вычисления можно проводить по формулам: P = a + b + c – периметр, p = P2 – полупериметр,

A = p ( p a)( p b)( p c) – площадь.

Вmain вводятся исходные данные, и вызывается функция triangle.

//Файл Triangle.cpp

#include <iostream.h> #include <math.h>

//triangle: вычисление периметра и площади треугольника

//возвращает 1, если треугольник существует и 0 если не существует int triangle(double a, double b, double c, double *p_perim, double *p_area)

//a, b, c - стороны треугольника

//p_perim - указатель на переменную для периметра

//p_area - указатель на переменную для площади

{

 

 

double p;

 

// Полупериметр

// Проверка существования треугольника

 

if(a > b + c || b > a + c || c > a + b)

 

return 0;

// Треугольник не существует, выход из функции

p = (a + b + c) / 2;

 

 

*p_perim = 2 * p;

 

// Периметр

*p_area = sqrt(p * (p - a)*(p - b)*(p - c));

// Площадь

return 1;

 

 

}

 

 

int main()

 

 

{

 

 

double r, s, t;

 

// Стороны треугольника

double P, A;

 

// Периметр и площадь

cout << "Введите три стороны треугольника: "; cin >> r >> s >> t;

if(triangle(r, s, t, &P, &A) == 0)

cout << "Такого треугольника не существует\n"; else

cout << "Периметр: " << P << ", площадь: " << A <<"\n";

120 10

return 0;

}

Так как в функцию triangle передается указатель p_perim на переменную для периметра, сама эта переменная получается внутри функции с помощью выражения *p_perim и ей присваивается вычисленное значение. Аналогично используется указатель p_area на переменную для площади.

При вызове triangle ей в качестве аргументов передаются &P и &A – адреса переменных P и A. Возвращаемое triangle значение сравнивается с 0. Если результат сравнения положительный, то печатается сообщение, что треугольник не существует, иначе печатаются значения P и A, вычисленные внутри функции triangle. Ниже приведены результаты, выдаваемые программой.

Введите три стороны треугольника: 3 4 5 Периметр: 12, площадь: 6

Взаимодействие формальных параметров и фактических аргументов функции triangle иллюстрируется рис.36. При вызове функции формальные параметры a, b, c получают значения фактических аргументов r, s, t; формальные параметры p_perim, p_area получают значения адресов внешних переменных P и A.

 

main

 

 

triangle

r

 

 

 

 

 

 

a

 

 

 

 

 

 

s

 

 

 

 

 

 

b

 

 

 

 

 

 

t

 

 

 

 

 

 

c

 

 

 

 

 

 

P

 

 

 

 

 

p_perim

 

 

 

 

A

 

 

 

 

 

p_area

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

 

 

 

 

 

 

Рис.37. Формальные параметры a, b, c получают значения внешних переменных r, s, t; p_perim и p_area получают значения адресов P и A

Указатели и ссылки 121

10.2. Указатели и массивы

Определение: int a[10];

создает массив из 10 элементов, то есть блок из 10 расположенных последовательно переменных целого типа с именами a[0], a[1], …, a[9].

Пусть определен указатель: int *p;

После присваивания p = &a[0];

указатель p будет содержать адрес нулевого элемента массива a. На рис.38 это показано стрелкой, причем для p нарисован прямоугольник, чтобы подчеркнуть, что этот указатель размещен где-то в памяти.

p

p+1

p+2

 

 

 

 

 

 

 

 

 

 

 

 

a:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a[0]

a[1]

 

 

 

 

 

 

 

a[9]

Рис.39. Массив в памяти и указатели на элементы массива

По определению, p + 1 указывает на следующий элемент массива, p + i указывает на i-й элемент после p, p - i указывает на i-й элемент перед p. Для выражений p + 1, p + 2 на рисунке прямоугольники не нарисованы, так как под них память не выделяется. Имея указатель на начало массива, можно получить доступ к любому его элементу, например, *p есть нулевой элемент массива, *(p + 1) – первый и т.д. Присваивание

*(p + 1) = 0;

обнуляет первый элемент массива.

По определению, имя массива имеет значение адреса начального элемента массива, поэтому имя массива имеет тип указателя на элемент массива, например, a имеет тип int*.

Доступ к i - му элементу массива можно получить, используя индексацию a[i] или выражение *(a + i).

Указатель – это переменная, которой можно присваивать различные значения, например,

p = a + 1;

Теперь p указывает на первый элемент массива a.