|
Программирование >> Программирование с использованием ajax
int myNumber = 5; Console.WriteLine( myNumber = {0} , myNumber); ShowDouble(myNumber); Console.WriteLine( myNumber = {0} , myNumber); текстовый вывод в окне консоли будет выглядеть так: myNumber = 5 удвоенное значение val =10 myNumber = 5 Вызов ShowDouble () с myNumber в качестве параметра никак не влияет на значение myNumber в Main (), хотя параметр val, которому оно присваивается, умножается на 2. Все это замечательно, но если все-таки нужно, чтобы значение myNumber изменялось, возникает проблема. При желании ее можно решить применением функции, возвращающей новое значение для myNumber, как показано ниже: static int DoubleNum(int val) { val *= 2; return val; Для вызова этой функции можно использовать такой код: int myNumber = 5; Console.WriteLine( myNumber = {0} , myNumber); myNumber = DoubleNum (myNumber) ; Console.WriteLine( myNumber = {0} , myNumber); Однако такой код труден для восприятия и не справляется с изменением значений множества переменных, передаваемых в виде параметров (поскольку функции возвращают единственное значение). Поэтому передавать параметр необходимо по ссылке (reference). Благодаря этому функция будет работать с той же переменной, которая указывается в вызове функции, а не просто переменной, которая имеет точно такое же значение. В результате любые вносимые в эту переменную изменения будут отражаться и в переменной, переданной в качестве параметра. Все, что для этого требуется - применить для параметра ключевое слово ref: static void ShowDouble (ref int val) val *= 2; Console.WriteLine( удвоенное значение val = {0} , val); Затем использовать его опять в вызове функции (обязательно!): int myNumber = 5; Console.WriteLine( myNumber = {0} , myNumber); ShowDouble (ref myNumber) ; Console.WriteLine( myNumber = {0} , myNumber); Тогда текстовый вывод в окне консоли будет выглядеть следующим образом: myNumber = 5 удвоенное значение val = 10 myNumber =10 На этот раз выполнение функции ShowDouble () повлияло на значение myNumber. Важно обратить внимание на два ограничения, которые следует соблюдать в случае использования переменной в качестве параметра ref. Во-первых, функция может приводить к изменению значения параметра-ссылки, поэтому в вызове функции должна обязательно использоваться только неконстантная переменнгш. Следовательно, такой код является недопустимым: 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); Выходные параметры Помимо передачи значений по ссылке можно еще также указывать, что данный параметр является выходным параметром, используя ключевое слово out, которое применяется тем же способом, что и ключевое слово ref (т.е. в виде модификатора перед параметром как в определении, так и в вызове функции). В сущности, он обеспечивает точно такое же поведение, как и параметр-ссылка, в том, что касается возврата значения параметра в конце выполнения функции использовавшейся в вызове функции переменной. Однако существуют два важных отличия. □ В качестве параметра ref применять неинициализированную переменную нельзя, а в качестве параметра out - можно. а Параметр out должен трактоваться как неприсвоенное значение функцией, которая его использует. Это означает, что хотя использовать неинициализированную переменную в качестве параметра out в вызывающем коде допускается, хранящееся в этой переменной значение при выполнении функции будет утрачиваться. Для примера рассмотрим функцию MaxValue (), которая уже демонстрировалась ранее и возвращает максимальное значение в массиве. Изменим ее так, чтобы она позволяла получать индекс того элемента, в котором находится максимальное значение. Чтобы не усложнять пример, пусть это будет индекс только первого вхождения этого значения при наличии множества элементов с таким же максимальным значением. Чтобы добиться такого поведения, достаточно добавить параметр out, изменив функцию, как показано ниже: static int MaxValue (int[] intArray, out int maxindex) int maxVal = intArray[0]; maxindex = 0; for (int i = 1; i < intArray.Length; i++) { if (intArray[i] > maxVal) { maxVal = intArray[i]; maxindex = i; return maxVal; Использовать эту функцию можно так: int[] myArray = (1, 8, 3, б, 2, 5, 9, 3, О, 2}; int maxindex; Console.WriteLine( Максимальное значение myArray равно {0} , MaxValue(myArray, out maxindex)); Console.WriteLine( Первое вхождение этого значения встречается в элементе {0} , maxindex + 1) ; Это приведет к получению следующего вывода: Максимальное значение myArray равно 9 Первое вхождение этого значения встречается в элементе 7 Обратите внимание на обязательное использование в вызове функции ключевых слов out и ref. К возвращенному здесь значению maxindex при отображении на экране была добавлена единица. Это сделано для того, чтобы преобразовать индекс в более привычную форму, когда отсчет начинается с 1, а нес 0. Область видимости переменных По мере прочтения предыдущего раздела наверняка возник вопрос о том, зачем необходим обмен данными с функциями. Все дело в том, что переменные в С# доступны только из локализованных областей кода. Говорят, что у каждой взятой переменной имеется так называемая область видимости, или контекст (scope), в пределах которой к ней можно получать доступ. Область видимости переменных является важной темой, объяснить которую легче всего на примере. В следующем практическом занятии демонстрируется ситуация с определением переменной в одной области видимости и попыткой получения к ней доступа из другой области. Практическое занятие! Определение и использование базовой функции 1. Внесите в файл Program.cs приложения ChOGExOl следующие изменения: class Program { static void Write О { Console.WriteLine ( myString = {0} , myString); static void Main(string [ ] args) { string myString = String defined in Main() ; Строка, определенная в функщда Main() Write О; Console.ReadKey О; 2. Скомпилируйте этот код и обратите внимание на сообщение об ошибке и предупреждение: The name myString does not exist in the current context The variable myString is assigned but its value is never used Имя myString не существует в текущем контексте Переменная myString присвоена, но ее значение никогда не используется
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |