Указатели в параметрах функции
Параметры функции в C++ могут представлять указатели. Указатели передаются в функцию по значению, то есть функция получает копию указателя. В то же время копия указателя будет в качестве значения иметь тот же адрес, что оригинальный указатель. Поэтому используя в качестве параметров указатели, мы можем получить доступ к значению аргумента и изменить его.
Например, пусть у нас будет простейшая функция, которая увеличивает число на единицу:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
void increment(int);
int main()
{
int n = 10;
increment(n);
std::cout << "main function: " << x << std::endl;
return 0;
}
void increment(int x)
{
x++;
std::cout << "increment function: " << x << std::endl;
}
Здесь переменная n передается в качестве аргумента для параметра x. Передача происходит по значению, поэтому любое изменение параметра x в функции increment никак не скажется на значении переменной n. Что мы можем увидеть, запустим программу:
increment function: 11
main function: 10
Теперь изменим функцию increment, использовав в качестве параметра указатель:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
void increment(int*);
int main()
{
int n = 10;
increment(&n);
std::cout << "main function: " << n << std::endl;
return 0;
}
void increment(int *x)
{
(*x)++;
std::cout << "increment function: " << *x << std::endl;
}
Для изменения значения параметра применяется операция разыменования с последующим инкрементом: (*x)++. Это изменяет значение, которое находится по адресу, хранимому в указателе x.
Поскольку теперь функция в качестве параметра принимает указатель, то при ее вызове необходимо передать адрес переменной: increment(&n);.
В итоге изменение параметра x также повлияет на переменную n:
increment function: 11
main function: 11
В то же время поскольку аргумент передается в функцию по значению, то есть функция получает копию адреса, то если внутри функции будет изменен адрес указателя, то это не затронет внешний указатель, который передается в качестве аргумента:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
void increment(int*);
int main()
{
int n = 10;
int *ptr = &n;
increment(ptr);
std::cout << "main function: " << n << std::endl;
return 0;
}
void increment(int *x)
{
int z = 6;
x = &z; // переустанавливаем адрес указателя x
std::cout << "increment function: " << *x << std::endl;
}
В функцию increment передается указатель ptr. При вызове функция получает копию этого указателя в виде парамета x. В функции изменяется адрес указателя x. Но это никак не затронет указатель ptr, так как он предствляет другую копию. В итоге поле переустановки адреса указатели x и ptr будут хранить разные адреса.
Результат работы программы:
increment function: 6
main function: 10