Oslash; передача параметров по ссылке

      Комментарии к записи Oslash; передача параметров по ссылке отключены

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

Механизм передачи параметров по ссылке

Вызов по ссылке хорош в смысле производительности, потому что он исключает накладные расходы на копирование больших объемов данных; в то же время он может ослабить защищенность, потому что вызываемая функция может испортить передаваемые в нее данные.

Вызов по ссылке можно осуществить двумя способами: с помощью ссылочных параметров и с помощью указателей. Ссылочный параметр — это ПСЕВДОНИМ соответствующего аргумента. Чтобы показать, что параметр функции передан по ссылке, после типа параметра в прототипе функции ставится символ амперсанда ; такое же обозначение используется в списке типов параметров в заголовке функции. В вызове такой функции реально в функцию передается не сама переменная, а ее адрес, полученный операцией адресации . Тогда упоминание в теле вызываемой функции переменной по имени ее параметра в действительности является обращением к исходной переменной в вызывающей функции, и эта исходная переменная может быть изменена.

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

// Типичная Ошибка!!

void GetArray(int *a){a=new int[10];couta[i];} void main(){ int* a;//передается указатель, а он – не определен)GetArray(a);PutArray(a);}

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

void GetArray(int* a) // ссылка на указатель!!

{

a=new int[10];

cout

for(int i=0; i

cina[i];

}

При передаче параметра по ссылке аргументом может быть ТОЛЬКО ПЕРЕМЕННАЯ (простая или структурированная). В этом случае в подпрограмму передается не значение переменной, а ее адрес. Для того, чтобы по нему могло быть занесено новое значение передаваемой в качестве параметра переменной, следует воспользоваться операцией, например, получения адреса — “”. При этом изменяется работа с данным аргументом в самой подпрограмме : необходимо параметр описать как указатель и использовать, при доступе к нему, операции работы с указателями, что, естественно, немного усложняет текст.

void swap (int *a, int *b){int t;t=*a;*a=*b;*b=t;} void main ( ){. . .swap (x,y);. . .} swap объявлена как функция с двумя аргументами типа указателей на int. При вызове функцииswar (x,y) адрес x запоминается в a и адрес y запоминается в b. Теперь для одной и той же ячейки существует два имени — синонимы. Ссылки *a и *b в функции swap действуют точно так же, как x и y в main. Присваивание внутри функции swap изменяет содержимое x и y. Компилятор проведет проверку типов аргументов при вызове swap в соответствии с forward-объявлении swap. Типы фактических аргументов соответствуют списку типов аргументов и списку формальных параметров.

Задача:Требуется в заданном массиве из целых чисел поменять местами 2-ой и 6-ой элементы. Требование: в главной программе должны быть только вызовы подпрограмм.

Решение

Создадим следующие процедуры:

o void GetMem(int * x, int n); — для того, чтобы отвести память под массив х из n элементов;

o void DoRandom(int *a, int n); — для того, чтобы задать значения элементов массива а из n элементов с помощью датчика случайных чисел;

o void PrintX(int *x, int n); — для того, чтобы напечатать массив х из n элементов;

o void Change(int*a, int*b); — для того, чтобы поменять местами значения элементов, расположенные по адресам a и b.;

/* функция меняет местами значения элементов по адресам а и в */

void Change(int*a, int*b)

{

int z = *a;

*a = *b;

*b = z;

}

/* функция выделяет память под массив */

void GetMem(int * x, int n)

{

x = new int [n];

}

/* функция создает массив ДСЧ */

void DoRandom(int *a, int n)

{

for (int i=0; i

a[i] = random(100);

}

/* функция печатает массив */

void PrintX(int *x, int n)

{

cout

for (int i=0; i

cout

cout

}

/* Головная программа */

void main()

{

int* x; // объявить указатель на массив х

GetMem(x,10); // отвести память под массив х

DoRandom(x,10); // задать элементы массива

PrintX(x,10); // напечатать массив

Change(x[2],x[6]); // поменять местами значения элементов

PrintX(x,10); // напечатать измененный массив

}

Статьи к прочтению:

Основы Java. Урок 19: Передача аргументов по значению и по ссылке


Похожие статьи: