Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс_ред.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.76 Mб
Скачать

Передача параметров

Функции без параметров встречаются не так уж часто. Причина здесь в том, что наличие параметров позволяет передавать при вызове одной и той же функции различные данные для обработки, что существенно увеличивает область применения и полезность такой функции.

Если функция должна получать параметры, то необходимо задать:

  • Список принимаемых функцией параметров в ее описании, а также тип каждого параметра;

  • Совпадающий по количеству значений список параметров при каждом вызове функции.

Это предполагает использование следующего кода:

static <возвращаемыйТип> <имяФункции>{<типПараметра> <имяПараметра>, . . . )

{

...

return <возвращаемоеЗначение>;

}

Здесь может быть произвольное число параметров, для каждого из которых указываются тип и имя. В качестве разделителя между параметрами используются запятые. Каждый из параметров доступен внутри данной функции в качестве переменной.

Например, следующая простая функция принимает два параметра типа double и возвращает их произведение:

static double product (double param1, double param2)

{

return param1 * param2;

}

Следующая функция принимает в качестве параметра массив целых чисел и возвращает наибольшее из них. Ее описание имеет следующий вид:

static int maxValue(int[] intArray)

{

int maxVal = intArray[0];

for (int i = 1; i < intArray.Length; i++)

{

if (intArray[i] > maxVal)

maxVal = intArray[i];

}

return maxVal;

}

Данная функция — maxValue() —имеет один параметр, который описан как массив типа int с именем intArray. Возвращаемое значение также имеет тип int.

Определение максимального значения представляет собой несложную задачу и выполняется за один цикл. Когда выполнение цикла завершено, переменная maxVal содержит наибольшее значение данного массива, которое и возвращается оператором return.

Код, расположенный в Main(), объявляет и инициализирует простой целый массив, который будет использоваться совместно с функцией maxValue():

int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2};

При вызове функции maxValue() значение присваивается переменной maxVal типа int:

int maxVal = maxValue(myArray);

Полученное значение можно вывести на экран с помощью Console.WriteLine() или использовать каким-либо иным способом:

Console.WriteLine("Максимум в массиве myArray равен {0}", maxVal);

Вся программа будет иметь вид:

using System;

namespace Function2

{

class Program

{

static void Main(string[] args)

{

int[] myArray = { -1, 8, 3, 6, 2, 5, -9, 3, 0, 2 };

int maxVal = maxValue(myArray);

Console.WriteLine("Максимум в массиве myArray равен {0}",

maxVal);

Console.ReadLine();

}

static int maxValue(int[] intArray)

{

int maxVal = intArray[0];

for (int i = 1; i < intArray.Length; i++)

{

if (intArray[i] > maxVal)

maxVal = intArray[i];

}

return maxVal;

}

}

}

Как видно из листинга, порядок появления функций в программе может быть любым, главное – чтобы все они были определены. Так как точкой входа в программу является функция Main(), то логично поставить ее на первое место, а затем определить все вызываемые из нее функции. В этом случае при просмотре текста программы от начала к концу файла легче понять, что выполняет данная программа (при просмотре кода Main()), а затем – как это происходит (при просмотре).

Массивы параметров

В С# предусмотрена возможность задания одного (и только одного) специального параметра функции. Этот параметр, который обязательно должен располагаться последним, известен под названием массива параметров. Он позволяет при обращении к функциям использовать переменное количество параметров. Массив параметров описывается посредством ключевого слова params.

Передача параметров по ссылке и по значению

Во всех предыдущих функциях применялись параметры, передаваемые по значению. Другими словами, мы передавали значение в переменную, которая затем использовалась внутри функции. Любые изменения, которые эта переменная претерпевала внутри функции, не оказывали никакого влияния на параметр, использованный при вызове функции. В качестве примера рассмотрим функцию, которая удваивает передаваемый ей параметр и выводит результат на экран:

static void showDouble(int val)

{

val *= 2;

Console.WriteLine("Удвоенное значение val = {0}", val) ;

}

В этой функции происходит удвоение передаваемого параметра. Если мы вызовем эту функцию из Main() следующим образом:

int myNumber = 5;

Console.WriteLine("До вызова функции myNumber = {0}", myNumber);

showDouble(myNumber);

Console.WriteLine("После вызова функции myNumber = {0}", myNumber);

Результат работы программы будет таким:

Таким образом, вызов функции showDoubl() с переменной myNumber в качестве параметра не оказывает никакого влияния на переменную myNumber, описанную в Main(), несмотря на то, что параметр, которому присваивается ее значение, удваивается.

Это достаточно удобно, если мы не хотим, чтобы значение передаваемого параметра изменялось после вызова функции. Но если мы пожелаем, чтобы значение переменной myNumber было изменено, возникнет проблема.

Можно воспользоваться функцией, которая возвращает новое значение переменной myNumber, и вызвать ее следующим образом:

int myNumber = 5;

Console.WriteLine("До вызова функции myNumber = {0}", myNumber);

myNumber = showDouble(myNumber);

Console.WriteLine("После вызова функции myNumber = {0}", myNumber);

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

Вместо этого следует передавать параметр по ссылке. Это означает, что функция будет работать именно с той переменной, которая использовалась при вызове функции, а не с переменной, которая имеет то же значение. Следовательно, любые изменения переменной, использованной внутри функции, отразятся на значении переменной, использовавшейся в качестве параметра. Для этого при описании параметра необходимо воспользоваться ключевым словом ref:

static void showDouble(ref int val)

{

val *= 2;

Console.WriteLine("Удвоенное значение val = {0}", val);

}

Вторично ключевое слово ref необходимо использовать при вызове функции (это обязательное требование, поскольку тот факт, что параметр передается по ссылке, является неотъемлемой частью описания этого параметра):

int myNumber = 5;

Console.WriteLine("До вызова функции myNumber = {0}", myNumber);

showDouble(ref myNumber);

Console.WriteLine("После вызова функции myNumber = {0}", myNumber);

В этом случае на консоль будет выведен следующий текст:

Для переменных, используемых в качестве параметров типа ref, имеются два ограничения. Во-первых, поскольку существует вероятность, что в результате вызова функции значение вызываемого по ссылке параметра будет изменено, то при вызове функции запрещается использовать переменные типа const. Отсюда следует, что следующий вызов является недопустимым:

const int myNumber = 5;

Console.WriteLine("До вызова функции myNumber = {0}", myNumber);

showDouble(ref myNumber);

Console.WriteLine("После вызова функции myNumber = {0}", myNumber);

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

int myNumber;

showDouble(ref myNumber);

Console.WriteLine("После вызова функции myNumber = {0}", myNumber);