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: Передача аргументов по значению и по ссылке
Похожие статьи:
-
Способ передачи параметров в подпрограмму
Существует несколько способов передачи параметров в подпрограмму. § Передача параметров по значению. Формальному параметру присваивается значение…
-
Использование стека для передачи параметров
Стек часто используется при обращении к процедурам для передачи параметров в процедуры. При передаче управления процедуре процессор автоматически…