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

126 10

{

// Исследуем библиотечную функцию синус

cout << "\nmax sin(x) при 0 < x < Pi = " << maxfun(sin, 0, M_PI, 50); // Исследуем функцию erf

cout << "\nmax erf (x) при -2 < x < 2 = " << maxfun(erf, -2, 2, 50); getch();

}

double erf (double x) // Определение функции для исследования

{

return exp(-x * x) / sqrt(2 * M_PI);

}

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

Для исследования выбраны библиотечная функция синус и функция erf ( x) = 21π ex2 .

Данная программа выводит:

max sin(x) при 0 < x < Pi = 0.999486 max erf(x) при -2 < x < 2 = 0.398278

10.7. Ссылки

Ссылка (reference) является альтернативным именем объекта. Пусть X некоторый тип, тогда ссылка на объект типа X объявляется с использованием X&. Например,

void f()

 

{

 

int i =1;

 

int& r = i;

// r и i ссылаются на одно и то же целое

int x = r;

// x = 1

r = 2;

// i = 2

}

 

Ссылку всегда надо инициализировать, чтобы она ссылалась на какой-нибудь объект, например,

int i = 1;

 

 

int& r1 = i;

// Правильно, r1

инициализирована

int& r2;

// Ошибка, отсутствует инициализация

extern int& r3;

// Правильно, r3

инициализируется в другом месте

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

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

Программа 28. Использование ссылок

В состав программы входит функция swap, меняющая значения своих аргументов, передаваемых в нее по ссылке, и функция max, возвращающая ссылку на максимальный из двух своих аргументов.

// Файл Referenc.cpp

void swap(int& a, int& b) // Обмен значений a и b

{

int tmp = a; a = b;

b = tmp;

}

int& max(int& a, int& b) // Возвращает ссылку на максимальное из a и b

{

return a > b ? a: b;

}

#include <iostream.h> #include <conio.h>

int main()

{

int x, y;

cout << "Введите два числа: "; cin >> x >> y;

cout << "x = " << x << ", y = " << y << endl; swap(x, y);

cout << "После обмена: \n";

cout << "x = " << x << ", y = " << y << endl; max(x, y) = 0;

cout << "Максимальное обнулили: \n";

cout << "x = " << x << ", y = " << y << endl; getch();

return 0;

}

Пример работы программы:

Введите два числа: 2 3 x = 2, y = 3

После обмена: x = 3, y = 2

128 10

Максимальное обнулили: x = 0, y = 2

При вызове функции swap ее параметры a и b инициализируются именами x и y, поэтому a и b становятся другими именами для переменных x и y, что и позволяет изменить x и y внутри функции.

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

Во многих случаях использование ссылок позволяет обойтись без указателей.

10.8. Операторы new и delete

Оператор new выделяет память под объект во время выполнения программы. Например, пусть в программе определен указатель:

double *pd;

// Указатель на double

Значение указателя pd после его создания не определено и его использование будет ошибкой. Инструкция:

pd = new double;

выделяет память под double, адрес которой присваивается pd. Теперь выделенную память можно использовать, например:

*pd = sqrt(3);

// Размещение в памяти значения

cout << *pd;

// Печать значения

После оператора new указывается тип создаваемого объекта. Оператор delete освобождает память, выделенную ранее оператором

new, например, delete pd;

Теперь указатель pd можно использовать для других целей.

Память, освобожденная оператором delete, может быть повторно использована под объекты, создаваемые оператором new.

Динамические массивы можно создавать оператором new[]. Например, массив из 80 символов можно создать инструкцией:

char *s = new char[80];

Для удаления динамических массивов служит оператор delete[], например,

delete[] s; // Удаление массива s

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

При освобождении памяти, выделенной оператором new, операторы delete и delete[] должны иметь возможность определять размер удаляемого объекта. Это обеспечивается тем, что под динамический объект памяти выделяется больше, чем под статический, обычно на одно слово, в котором хранится размер объекта.

Программа 29. Выделение и освобождение памяти

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

// Файл AllocMem.cpp

 

#include <iostream.h>

 

#include <math.h>

 

int main()

 

{

 

double *pd;

// Указатель

// Вывод адреса, хранящегося в pd

 

cout << hex << "\n Address(pd) = " << pd;

pd = new double;

// Выделение памяти

*pd = sqrt(3);

// Занесение в память значения

// Вывод адреса и значения

 

cout << "\n Address(pd) = " << pd << ", Value(*pd) = " << *pd;

char *s;

// Символьный указатель

cout << "\n Address(s) = " << (int*)s;

delete pd;

// Освобождение памяти

s = new char[80];

// Создание динамического массива

cout << "\n Address(s) = " << (int*)s << ", Value(s) = " << s;

cout << "\n Input a string \n";

// Введите строку

cin.getline(s, 80);

// Использование памяти

cout << "Address(s) = " << (int*)s << ", Value(s) = " << s; cin.get();

return 0;

}

Программа выводит следующее:

Address(pd) = 1

Address(pd) = 8f5fc0, Value(*pd) = 1.73205 Address(s) = 100

Address(s) = 8f5fc0, Value(s) = ∟vg2∟vg2 Input a string

qwerty

Address(s) = 8f5fc0, Value(s) = qwerty