Передача через указатель
С точки зрения удобства программирования, передавать значения, которые могут изменяться внутри функции лучше всего через ссылку (а не через указатель). Чтобы в этом разобраться, ниже описан возможный, но не самый лучший способ передачи параметров - по указателю.
Если передавать параметры через указатель (так называемый С-стиль), код функции выглядит так:
mul5(int *x)
{
*x = *x * 5;
}
Вызов:
int var=10;
mul5(&var); // Здесь символ & обозначает операцию взятия адреса переменной
Такой синтаксис неудобен. Внутри тела функции, перед переменной, которая является указателем, приходится ставить звездочку * для работы со значением, на который указывает указатель. Кроме того, при вызове функции приходится ставить амперсанд & перед именем переменной для того, чтобы передать адрес переменной (который будет принят в функцию как указатель).
Передача через ссылку
Если передавать параметры через ссылку, код функции выглядит так:
mul5(int &x)
{
x = x * 5;
}
А вызов выглядит так:
int var=10;
mul5(var);
Видно, что нет никаких разыменовываний в теле функции функции. Так же при таком вызове не требуется передача адреса переменной.
Однако, следует помнить, что такая передача по ссылке возможна только для единичных типов C/C++. И не работает для передачи массивов!
Поэтому, к примеру, если функция принимает:
- одномерный массив block из элементов char, элементы которого надо изменить внутри функции (обозначим это как сложный/составной тип)
- целочислительную переменную shift, которую тоже надо изменить внутри функции (это простой базовый тип)
то реализация функции будет выглядеть так:
void clear(unsigned char *block, int &shift)
{
block[shift]=0;
shift++;
}
А вызов функции будет выглядеть так:
unsigned char* anyBlock="Long string";
int anyShift=0;
int len=strlen(anyBlock);
for(int i=0; i<len; ++i)
clear(anyBlock, anyShift); // Вызов функции
То есть, в вызове нет никаких спецсимволов указателей/адресов ни для первого ни для второго параметра. Для первого параметра нет спецсимвола взятия адреса (хоть и идет работа с указателем) из-за того, что имя массива имеет тип указателя. Для второго параметра нет спецсимвола взятия адреса из-за того, что передача идет по ссылке.
При таком вызове будут изменяться как ячейки массива anyBlock, так и переменная anyShift.
|