Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР15-С++24-мая-2012.doc
Скачиваний:
23
Добавлен:
23.09.2019
Размер:
1.07 Mб
Скачать

1.4. Передача параметра по ссылке

В языке С все аргументы функции передаются по значению. Это значит, что при вызове функции в системный стек помещаются фактические значения аргументов функции. В функции создаются локальные копии аргументов, значения которых считываются из стека. Далее функция использует эти локальные переменные и может изменять их. При выходе из функции локальные переменные уничтожаются, изменённые значения параметров теряются. Таким образом, в языке С вызванная функция не может изменить значения переменных, указанных в качестве фактических параметров при обращении к ней. Например, функция swap(), которая должна менять значения параметров местами, не будет этого делать:

void swap(int a, int b)

{

int tmp=a; a=b; b=tmp;

} //.

Но тем не менее функцию можно приспособить для изменения аргументов. Для этого необходимо в качестве параметра передавать адрес переменной, которую надо изменять, т. е. передавать указатель на переменную. Такой приём в языке С называется передачей параметра через указатель. Вызванная функция должна описывать аргумент как указатель и обращаться к фактической переменной косвенно, через разыменование указателя. Теперь функцию swap() мож-

но описать следующим образом:

void swap(int *a, int *b)

{

int tmp=*a; *a = *b; *b=tmp;

} //.

Тогда для обмена местами значений переменных x и y необходимо использовать функцию swap(&x,&y).

Ещё одним способом косвенной передачи параметра функции является передача по ссылке. Тогда аргументами функции swap() будут «ссылки» на другие переменные

void swap(int &a, int &b)

{

int tmp=a; a = b; b=tmp;

} //.

При обращении к функции в качестве фактических параметров необходимо указывать имена переменных x и y: swap(x,y). Подробнее о ссылках можно почитать в [2].

1.5. Динамическое выделение памяти

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

указатель = new тип;

например,

int *p; // указатель на целое

p = new int; // выделяем память.

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

*p = 155; // присвоили значение.

Когда динамически выделенная память больше не нужна её можно освободить с помощью оператора delete:

delete указатель;

например,

delete p; // освободили память.

Удаления указателя при этом не происходит, память, адрес которой находится в указателе, объявляется свободной.

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

Для работы с динамической памятью используются стандартные функции библиотеки alloc.h:

void *malloc(size) и void *calloc(n, size) – выделяют блок памяти размером size и nsize байт соответственно; возвращают указатель на выделенную область, при ошибке – значение NULL;

void free(bf); – освобождает ранее выделенную память с адресом bf.

Другим, более предпочтительным подходом к динамическому распределению памяти является использование операций языка С++ new и delete.

Операция new возвращает адрес ОП, отведенной под динамически размещенный объект, при ошибке – NULL, а операция delete освобождает память.