Читать в оригинале

<< ПредыдущаяОглавлениеСледующая >>


3.3.3. Локальные переменные

Перейдем теперь к рассмотрению локальных переменных. Во всех языках программирования, в том числе и в C#, основной контекст, в котором появляются переменные, - это процедуры. Переменные, объявленные на уровне процедуры, называются локальными, - они локализованы в процедуре.

В C# переменную можно объявлять в любой точке процедурного блока. Область ее видимости распространяется от точки объявления до конца процедурного блока. Процедурный блок имеет сложную структуру; в него могут быть вложены другие блоки, связанные с операторами выбора, цикла и так далее. В каждом таком блоке, в свою очередь, допустимы вложения блоков. В каждом внутреннем блоке допустимы объявления переменных. Переменные, объявленные во внутренних блоках, локализованы именно в этих блоках, их область видимости и время жизни определяются этими блоками. Локальные переменные начинают существовать при достижении вычислений в блоке точки объявления и перестают существовать, когда процесс вычисления завершает выполнение операторов блока.

Давайте обратимся к примеру. В класс Testing добавлен метод с именем ScopeVar, вызываемый в процедуре Main.

Вот код этого метода:

public void SimpleVars() {
//Объявления локальных переменных
int x, s;               //без инициализации
int y = 0, u = 77; //обычный способ инициализации
//допустимая инициализация
          float w1 = 0f, w2 = 5.5f, w3 = w1 + w2 + 125.25f;
          //допустимая инициализация в объектном стиле
          int z = new int();
          //Недопустимая инициализация.
          //Конструктор с параметрами не определен
          //int v = new int(77);
          x = u + y; //теперь x инициализирована
          if (x > 5) s = 4;
          for (x = 1; x < 5; x++) s = 5;
          //Инициализация в if и for не рассматривается,
          //поэтому s считается неинициализированной переменной
          //Ошибка компиляции:использование неинициализированной переменной
           //Console.WriteLine("s= {0}",s);
} //SimpleVars
/// <summary>
/// Анализ области видимости переменных
/// </summary>
/// <param name="x"></param>
public void ScopeVar(int x) {
          //int x=0;
          int y = 77;
          string s = name;
          if (s == "Точка1") {
            int u = 5;
            int v = u + y;
            x += 1;
            Console.WriteLine("y= {0}; u={1}; v={2}; x={3}", y, u, v, x);
          } //if then
          else {
            int u = 7;
            int v = u + y;
            Console.WriteLine("y= {0}; u={1}; v={2}", y, u, v);
          } //else
          //Console.WriteLine("y= {0}; u={1}; v={2}",y,u,v);
          //Локальные переменные не могут быть статическими.
          //static int Count = 1;
          //Ошибка: использование sum до объявления
            //Console.WriteLine("x= {0}; sum ={1}", x,sum);
            int i;
            long sum = 0;
            for (i = 1; i < x; i++) {
                        //ошибка: коллизия имен: y
                        //float y = 7.7f;
                        sum += i;
          } //for
          Console.WriteLine("x= {0}; sum ={1}", x, sum);
} //ScopeVar

Отметим, что в теле метода встречаются имена полей, аргументов и локальных переменных. Эти имена могут совпадать. Например, имя x имеет поле класса и формальный аргумент метода. В языке C# разрешено иметь локальные переменные с именами, совпадающими с именами полей класса, - в нашем примере таким является имя y; однако, запрещено иметь локальные переменные, имена которых совпадают с именами формальных аргументов. Этот запрет распространяется не только на внешний уровень процедурного блока, что вполне естественно, но и на все внутренние блоки.

В процедурный блок вложены два блока, порожденные оператором if. В каждом из них объявлены переменные с одинаковыми именами u и v. Это корректные объявления, поскольку время существования и области видимости этих переменных не пересекаются. Итак, для невложенных блоков разрешено объявление локальных переменных с одинаковыми именами. Отметим также, что переменные u и v перестают существовать после выхода из блока, так что операторы печати, расположенные внутри блока, работают корректно, а оператор печати вне блока приводит к ошибке, - u и v здесь не видимы, кончилось время их жизни. По этой причине оператор закомментирован.

Выражение, проверяемое в операторе if, зависит от значения поля name. Значение поля глобально для метода и доступно всюду, если только не перекрывается именем аргумента (как в случае с полем x) или локальной переменной (как в случае с полем y).

Во многих языках программирования разрешено иметь локальные статические переменные, у которых область видимости определяется блоком, но время их жизни совпадает со временем жизни проекта. При каждом повторном входе в блок такие переменные восстанавливают значение, полученное при предыдущем выходе из блока. В языке C# статическими могут быть только поля, но не локальные переменные. Незаконная попытка объявления static переменной в процедуре ScopeVar закомментирована. Попытка использовать имя переменной в точке, предшествующей ее объявлению, также незаконна и закомментирована.

 



<< ПредыдущаяОглавлениеСледующая >>