Напомним, что передача аргументов в функцию может быть произведена тремя способами: по значению, по ссылке, по указателю. Мы уже рассматривали ситуации, когда необходимо использовать передачу аргументов по ссылке. В этой же ситуации можно использовать и передачу по указателю.
Рассмотрим две версии программы, в которой используется функция для перевода дюймов в сантиметры.
Передача аргумента по ссылке
#include <iostream>
#include <conio>
using namespace std;
void centimize(double& v);
int main() {
double var;
cout << "Vvedite kol-vo duymov: ";
cin >> var;
centimize(var);
cout << "Eto " << var << " sm" << endl;
getch(); return 0;
}
void centimize(double& v) {
v = v*2.54; // v — это то же самое, что и var
}
| Передача аргумента по указателю
#include <iostream>
#include <conio>
using namespace std;
void centimize(double* ptr);
int main() {
double var;
cout << "Vvedite kol-vo duymov: ";
cin >> var;
centimize(&var);
cout << "Eto " << var << " sm" << endl;
getch(); return 0;
}
void centimize(double* ptr) {
*ptr = *ptr * 2.54; // *ptr — это то же, что и var
}
|
Как видно из приведённого примера, передача указателя в функцию в качестве аргумента довольно похожа на передачу по ссылке. Эти два механизма позволяют переменной вызывающей программы быть изменённой в функции. Однако эти механизмы различны. Ссылка – это псевдоним (синоним) переменной, а указатель – это адрес переменной. Таким образом, при использовании указателей функция передаёт в качестве аргумента адрес переменной centimize(&var);. Так как функция получает адрес, то необходимо использовать операцию разыменовывания для доступа к значению, расположенному по этому адресу.
Рассмотрим следующий пример, демонстрирующий использование указателей при передаче массивов в функцию.
…
const int MAX = 5; // количество элементов в массиве
void centimize(double* ptr); // прототип функции
int main() {
double arr[MAX] = { 10.0, 43.1, 95.9, 58.7, 87.3 }; //дюймы
centimize(arr); // переводим все элементы массива в сантиметры
for(int j = 0; j < MAX; j++) // покажем, что у нас получилось
cout << "Element [" << j << "] = " << arr[j] << " sm" << endl;
getch(); return 0;
}
//---------------------------------------------------------------------------
void centimize(double* ptr) {
for(int j = 0; j < MAX; j++)
*ptr++ *= 2.54; // или *(ptr + j) *= 2.54;
}
Так как имя массива является его адресом, то нет надобности использовать операцию взятия адреса & при вызове функции: centimize(arr);. Унарные операции * и ++ имеют правую ассоциативность, поэтому компилятор интерпретирует выражение *ptr++ как *(ptr++) и увеличивает указатель, а не то, на что он указывает. Таким образом, здесь сначала увеличивается указатель, а затем к результату применяется операция разыменовывания.