Механизм параметров является основным способом обмена информацией между вызываемой и вызывающей функциями. В операторе вызова функции записывают аргументы функции, а в заголовке описания функции перечисляют параметры.
В С++ передача параметров осуществляется тремя способами:
· по копии (или по значению);
· по адресу (или через указатель);
· по ссылке.
Это определяется видом объявления параметра в заголовке функции.
Рассмотрим все три способа передачи на примере функции обмена Change(). Ей передаются два параметра, и она должна поменять местами их значения.
1. Передача по копии (по значению):
void Change(int X, int Y) // определение функции{ int temp; temp = X; X = Y; Y = temp;}//-------------------------------------------------------------------- void main(){ int A = 10, B = 20; Change(A, B); // вызов функции printf (“\n A = %d B = %d”, A, B); // A = 10 B = 20 (замена не состоялась) getch ();}При передаче по значению объявление параметра похоже на объявление переменной: Тип ИмяПараметра. Такой параметр считается отдельной локальной переменной в теле функции. Ни в заголовке, ни в теле функции не должно быть других параметров или переменных с таким же именем.
|
|
Опишем работу программы. В области видимости функции main() существуют две локальные переменные A и B, которые проинициализированы значениями 10 и 20. В момент вызова функции Change() в стеке создаются параметры X и Y, которые получают копии значений аргументов A и B, а также переменная temp. Затем с помощью этой переменной происходит перестановка значений параметров X и Y (прежние значения выделены красным цветом). Однако по окончании работы функции Change() переменные X, Y и temp уничтожаются, поскольку являются локальными переменными, а значения аргументов A и B остаются неизменными.
Таким образом, функция Change() не решает поставленной перед ней задачи. Тем не менее, данный пример иллюстрирует особенность использования параметров-копий: никакие изменения значения параметра внутри функции не отражаются на значении переменной-аргумента, так как параметр является локальной переменной. Это способ передачи параметров в C++ используется по умолчанию.
2. Передача по адресу (через указатель):
void Change(int *X, int *Y) // определение функции{ int temp; temp = *X; *X = *Y; *Y = temp;}//-------------------------------------------------------------------- void main(){ int A = 10, B = 20; Change(&A, &B); // вызов функции printf (“\n A = %d B = %d”, A, B); // A = 20 B = 10 (замена состоялась) getch ();}Способ передачи параметров по адресу используется для того, чтобы через указатели обеспечить непосредственный доступ к значениям аргументов. В момент вызова функции Change() в стеке создаются параметры-указатели X и Y, которые получают копии адресов аргументов A и B. Теперь параметры X и Y указывают на аргументы A и B. Несмотря на то, что функции Change() не известны имена аргументов A и B, ей известны их адреса, поэтому она имеет доступ к их значениям. С помощью переменной temp происходит перестановка значений аргументов A и B (прежние значения выделены красным цветом). По окончании работы функции Change() переменные X, Y и temp уничтожаются, поскольку являются локальными переменными, но аргументы A и B остаются с новыми значениями. Таким образом, функция выполнила поставленную задачу.
|
|
3. Передача по ссылке:
void Change(int &X, int &Y) // определение функции{ int temp; temp = X; X = Y; Y = temp;}//-------------------------------------------------------------------- void main(){ int A = 10, B = 20; Change(A, B); // вызов функции printf (“\n A = %d B = %d”, A, B); // A = 20 B = 10 (замена состоялась) getch ();}Этот способ передачи параметров появился в C++ для того, чтобы упростить работу с указателями. При передаче по ссылке объявление параметра представляет собой объявление ссылки без инициализации: Тип &ИмяПараметра. Параметр-ссылка локальна в функции: ни в заголовке, ни в ее теле не должно быть объявлено других параметров и переменных с таким же именем. Инициализация параметра-ссылки выполняется во время вызова функции.
В самом простом случае при вызове функции в качестве аргумента задается имя переменной. Тип переменной-аргумента должен совпадать с типом параметра-ссылки. Ссылка становится альтернативным именем аргумента, поэтому любые действия, выполняемые со ссылкой в теле функции, мгновенно отражаются на состоянии аргумента.
В момент вызова функции Change() у аргументов A и B появляются вторые имена X и Y. Поэтому функция Change фактически напрямую работает с исходными переменными A и B и изменяет их.
Использование параметров-ссылок вместо передачи по значению или по адресу более эффективно, поскольку:
1) не требуется памяти для копирования аргументов в локальные переменные;
2) не требуется времени на их создание и уничтожение.
Поэтому программы с параметрами-ссылками работают быстрее и используют меньше памяти. Это имеет значение при передаче структур данных большого объема.
Передача параметра по ссылке также используется, если функция должна возвратить не один результат, а несколько.
Если требуется запретить изменение параметра, передаваемого по адресу или по ссылке, то используется модификатор const, например:
int Func(int a, const double &b);СОВЕТ Рекомендуется указывать const перед всеми параметрами, изменение которых в функции не предусмотрено. Это облегчает отладку. Кроме того, на место параметра типа const & может передаваться константа.
Параметры, передаваемые в функцию, могут быть любого типа (например, вещественного, структурой, перечислением, объединением, указателем), кроме массива или функции, которые передаются с помощью указателей.