Московский государственный университет имени М.В.Ломоносова
Опубликован: 18.09.2006 | Доступ: свободный | Студентов: 1869 / 118 | Оценка: 4.32 / 3.36 | Длительность: 27:14:00
ISBN: 978-5-9556-0067-3
Лекция 10:

Основные конструкции языков Java и C#

Инструкции

Большинство видов инструкций в Java и C# являются общими и заимствованы из языка C. В обоих языках есть понятие блока — набора инструкций, заключенного в фигурные скобки.

  • Пустая инструкция ; допускается в обоих языках.
  • Декларации локальных переменных устроены совершенно одинаково — указывается тип переменной, затем ее идентификатор, а затем, возможно, инициализация.

    Инициализировать переменную можно каким-то значением ее типа. Использование неинициализированных переменных во многих случаях определяется компилятором и считается ошибкой (но не всегда). Однако даже при отсутствии инициализации переменной, ей все равно будет присвоено значение по умолчанию для данного типа.

    Массивы могут быть инициализированы с помощью специальных выражений, перечисляющих значения элементов массива, например

    int[][] array = new int[][]{{0, 1}, {2, 3, 4}}; Ag
  • Инструкция может быть помечена с помощью метки, которая стоит перед самой инструкцией и отделяется от нее с помощью двоеточия.
  • Инструкция может быть построена добавлением точки с запятой в конец выражения определенного вида. Такое выражение должно быть одним из следующих:
    • присваиванием;
    • выражением, в котором последним оператором было уменьшение или увеличение на единицу ( ++, -- ), все равно, префиксное или постфиксное;
    • вызовом метода в объекте или классеC# — еще и вызовом делегата);
    • созданием нового объекта.
  • Условная инструкция имеет вид
    if(expression) statement Ag

    или

    if(expression) statement else statement1 Ag

    где expression — выражение логического типа (или приводящегося к логическому), а statement и statement1инструкции.

  • Инструкция выбора имеет вид
    switch(expression) { … } Ag

    Внутри ее блока различные варианты действий для различных значений выражения expression описываются с помощью списков инструкций, помеченных либо меткой case с возможным значением выражения, либо меткой default. Группа инструкций, помеченная default, выполняется, если значение выражения выбора не совпало ни с одним из значений, указанных в метках case. Один набор инструкций может быть помечен несколькими метками. Наборы инструкций могут отделяться друг от друга инструкциями break ;

    Тип expression может быть целочисленным или приводящимся к нему, либо перечислимым типом. В C# допускается использование для выбора выражений типа string.

    Значения, которые используются в метках case, должны быть константными выражениями.

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

    В C# группа инструкций для одного значения (включая и группу, помеченную default ) всегда должна оканчиваться либо break, либо goto default, либо goto case value с каким-то из значений, указанных в рамках той же инструкции выбора.

    public class A
    {
      public static void main(String[] args)
      {
        if(args.length > 0)
        {
          int n = Integer.parseInt(args[0]);
          switch(n)
          {
            case 0: 
              System.out.println("n = 0");
    
            case 1: 
              System.out.println
                ("n = 0 or n = 1");
              break;
            case 2:case 3: 
              System.out.println
                ("n = 2 or n = 3");
              break;
            default:
              System.out.println
                ("n is out of [0..3]");
    
          }
        }
        else
          System.out.println("No arguments");
      }
    }
    using System;
    
    public class A
    {
      public static void Main(string[] args)
      {
        if(args.Length > 0)
        {
          int n = Int32.Parse(args[0]);
          switch(n)
          {
            case 0:
              Console.WriteLine("n = 0");
              goto case 1;
            case 1: 
              Console.WriteLine
                ("n = 0 or n = 1");
              break;
            case 2:case 3: 
              Console.WriteLine
                ("n = 2 or n = 3");
              break;
            default:
              Console.WriteLine
                ("n is out of [0..3]");
              break;
          }
        }
        else
          Console.WriteLine("No arguments");
      }
    }
  • Циклы while и do в обоих языках устроены одинаково:
    while(expression) statement Ag
    do statement while(expression); Ag

    Здесь expression — логическое выражение, условие цикла, statement — тело цикла. Правила выполнения этих циклов фактически заимствованы из языка C. Первый на каждой итерации проверяет условие и, если оно выполнено, выполняет свое тело, а если нет — передает управление дальше. Второй цикл сначала выполняет свое тело, а потом проверяет условие.

  • Цикл for в обоих языках заимствован из языка C.
    for(A; B; C) statement Ag

    выполняется практически как

    A; while(B) { statement  C; } Ag

    Любой из элементов A, B, C может отсутствовать, B должно быть выражением логического типа (при отсутствии оно заменяется на true ), A и С должны быть наборами выражений ( A может включать и декларации переменных), разделенных запятыми.

    Помимо обычного for, в обоих языках имеется специальная конструкция для цикла, перебирающего элементы коллекции.

    В Java синтаксис цикла перебора элементов коллекции такой:

    for ( finalopt type id : expression )
      statement

    При этом выражение expression должно иметь тип java.lang.Iterable или тип массива.

    В первом случае такой цикл эквивалентен следующему ( T далее обозначает тип результат метода iterator() у expression, v — нигде не используемое имя).

    for(T v = expression.iterator();
        v.hasNext(); )
    {
      finalopt type id = v.next();
      statement
    }

    Во втором случае, когда expressionмассив типа T[], эта конструкция эквивалентна следующей ( a, i — нигде не используемые имена)

    T[] a = expression;
    for(int i = 0; i < a.length; i++)
    {
      finalopt type id = v.next();
      statement
    }

    В C# синтаксис цикла перебора элементов коллекции такой:

    foreach ( type id in expression )
      statement

    Выражение expression должно быть массивом, или иметь тип System.Collections.IEnumerable или System.Collections.Generic.IEnumerable <T>, или же его тип должен иметь метод GetEnumerator(), результат которого, в свою очередь, должен иметь свойство Current и метод MoveNext().

    Тип результата метода GetEnumerator() во всех случаях, кроме массива, называется типом итератора (enumerator type). Тип свойства Current, которое имеется у типа итератора, должен совпадать с type.

    Пусть тип итератора E, а e — неиспользуемое имя. Тогда приведенная конструкция, с точностью до некоторых деталей, эквивалентна следующей.

    E e = expression.GetEnumerator();
    while(e.MoveNext())
    {
      type id = (type)e.Current;
      statement
    }

    Опущенные детали касаются освобождения ресурсов, используемых итератором (см. далее описание инструкции using ).

    Пример использования перебора элементов коллекции:

    Пример использования перебора элементов коллекции:

    public class A
    {
      public static void main(String[] args)
      {
        int i = 1;
        for(String s : args)
          System.out.println((i++) +
            "-th argument is " + s);
      }
    }
    using System;
    
    public class A
    {
      public static void Main(string[] args)
      {
        int i = 1;
        foreach (string s in args)
          Console.WriteLine((i++) +
            "-th argument is " + s);
      }
    }
  • Инструкции прерывания break и continue также заимствованы из C.

    Инструкция break прерывает выполнение самого маленького содержащего ее цикла и передает управление первой инструкции после него. Инструкция continue прерывает выполнение текущей итерации и переходит к следующей, если она имеется (т.е. условие цикла выполнено в сложившейся ситуации), иначе тоже выводит цикл.

    При выходе с помощью break или continue за пределы блока try (см. ниже) или блока catch, у которых имеется соответствующий блок finally, сначала выполняется содержимое этого блока finally.

    В Java инструкция break используется для прерывания выполнения не только циклов, но и обычных блоков (наборов инструкций, заключенных в фигурные скобки).

    Более того, после break (или continue ) может стоять метка. Тогда прерывается выполнение того блока/цикла (или же начинается новая итерация того цикла), который помечен этой меткой. Этот блок (или цикл) должен содержать такую инструкцию внутри себя.

                                                   
  • Инструкция возврата управления return используется для возврата управления из операции (метода, оператора, метода доступа к свойству и пр., см. далее). Если операция должна вернуть значение некоторого типа, после return должно стоять выражение этого же типа.
  • Инструкция создания исключительной ситуации throw используется для выброса исключительной ситуации. При этом после throw должно идти выражение, имеющее тип исключения.

    Исключение (exception) представляет собой объект, содержащий информацию о какой-то особой (исключительной) ситуации, в которой операция не может вернуть обычный результат. Вместо обычного результата из нее возвращается объект-исключение — при этом говорят, что исключение было выброшено из операции. Механизм этого возвращения несколько отличается от механизма возвращения обычного результата, и обработка исключений оформляется иначе (см. следующий вид инструкций ), чем обработка обычных результатов работы операции.

  • Исключения в обоих языках относятся к особым типам — классам исключений. Только объекты таких классов могут быть выброшены в качестве исключений. Классами исключений являются все наследники классов java.lang.Throwable в Java и System.Exception в C#.
  • Объекты- исключения содержат, как минимум, следующую информацию.
    • Сообщение о возникшей ситуации (его должен определить автор кода операции, выбрасывающей это исключение ).

      В Java это сообщение можно получить с помощью метода String getMessage(), а в C# — с помощью свойства string Message.

    • Иногда возникают цепочки "наведенных" исключений, если обработка одного вызывает выброс другого. Каждый объект-исключение содержит ссылку на другое исключение, непосредственно вызвавшее это. Если данное исключение не вызвано никаким другим, эта ссылка равна null.

      В Java эту ссылку можно получить с помощью метода Throwable getCause(), а в C# — с помощью свойства System.Exception.InnerException.

    • Для описания ситуации, в которой возникло исключение, используется состояние стека исполнения программы — список методов, которые вызывали друг друга перед этим, и указание на место в коде каждого такого метода. Это место обозначает место вызова следующего метода по стеку или, если это самый последний метод, то место, где и возникло исключение. Обычно указывается номер строки, но иногда он недоступен, если соответствующий метод присутствует в системе только в скомпилированном виде или является внешним для Java -машины.

      Информация о состоянии стека на момент возникновения исключения, как и его сообщение, автоматически выводится в поток сообщений об ошибках, если это исключение остается необработанным в программе.

      В Java состояние стека для данного исключения можно получить с помощью метода StackTraceElement[] getStackTrace(), возвращающего массив элементов стека. Каждый такой элемент несет информацию о файле ( String getFileName() ), классе ( String getClassName() ) и методе ( String getMethodName() ), а также о номере строки ( int getLineNumber() ).

      В C# можно сразу получить полное описание состояния стека в виде одной строки с помощью свойства string StackTrace.

Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?