Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЛАВА 7 Указатели.doc
Скачиваний:
25
Добавлен:
29.02.2016
Размер:
143.36 Кб
Скачать

Функции и указатели

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

Из главы 5 мы уже узнали, как изменить значения аргументов, передаваемых в функцию, используя ссылки (см. примеры 5.7, 5.8). Однако, поскольку многие программисты С++ используют указатели для изменения значений аргументов, необходимо знать и такой вариант программирования.

Передача аргументов в функцию по указателю

Рассмотрим, как изменить значения аргументов, передаваемых в функцию, используя указатели:

  • для изменения значения аргумента функция должна знать адрес соответствующего аргумента;

  • используя операцию адреса (&), программа может передать адрес аргумента в функцию при её вызове;

  • когда функция получает адрес аргумента, она должна объявить соответствующий параметр как указатель (предваряя имя параметра звездочкой);

  • если функции требуется использовать значение, на которое ссылается (указывает) указатель, функция должна предварять имя параметра-указателя звездочкой, т.е. операцией разыменования (*).

Например, в следующем фрагменте программы параметром функции является указатель на тип int, а значением аргумента, передаваемого программой в функцию – адрес переменной:

int main(){

int y = 5; fun(&y);

cout<<y<<endl; // 6

}

void fun(int * x){

(*x)++; cout<<*x<<endl; // 6

}

В Примере 7.1. аргументы функции change() передаются по указателю (версия функции change() для случая передачи аргументов по ссылке была рассмотрена в 5-ой главе, Пример 5.7).

// Пример 7.1. Обмен значений двух переменных оформить в виде

// функции. change() Аргументы в функцию передавать по указателю.

#include <iostream>

using namespace std;

void change(int*, int*);

int main(){

int a = 10, b = 5;

change(&a, &b);

cout<<"Posle perestanovki(main): ";

cout<<"a = "<<a<<", b = "<<b<<endl; // a = 5, b = 10

system("pause");

}

void change(int * x, int * y){

cout<< "Do perestanovki(change): ";

cout<<"x = "<<*x<<", y = "<<*y<<endl; // x = 10, y = 5

int z = *x; *x = *y; *y = z;

cout<< "Posle perestanovki(change):\n";

cout<<"x = "<<*x<<", y = "<<*y<<endl; // x = 5, y = 10

}

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

// Пример 7.2. Расположить значения переменных а, в, с в порядке

// возрастания, используя функцию перестановки переменных change().

// Аргументы в функцию передавать по указателю.

#include <iostream>

using namespace std;

void change(int *, int *);

int main(){

int a, b, c;

cout<<"Vvedi a, b, c = "; cin>>a>>b>>c;

if(a > b) change(&a, &b);

if(b > c) change(&b, &c);

if(a > b) change(&a, &b);

cout<<" a = " << a << " b = "<<b<<" c = "<<c<<endl;

system("pause");

}

void change(int * x, int * y){

int temp;

temp = *x; *x = *y; *y = temp;

}

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