Cамоучитель по VB.NET



 

Ускоренная проверка


Если компилятор обнаруживает, что проверенная часть сложного логического условия однозначно определяет результат, он не проверяет остаток выражения. Это называется ускоренной проверкой (short curcuiting). Например, если в следующем примере переменная foo ложна, компилятор не проверяет переменную bar:

If foo And bar Then...

Так было в VB .NET бета-версии 1, но в прежних версиях VB ускоренная проверка не применялась. После многочисленных жалоб разработчики Microsoft вернули старую интерпретацию логических операторов And и Or и добавили новые ключевые слова AndAlso и OrElse, поддерживающие ускоренную проверку:

If foo AndAlso Then...

 

Select Case

В качестве альтернативы для громоздких конструкций с множеством Elself в VB .NET была сохранена команда Select Case, упрощающая принятие решений в зависимости от состояния числовой или строковой переменной. Пример:

Select Case average

Case Is > 90

Console.WriteLine("A")

Case Is > 80

Console. Wri teLi ne("B")

Case Is > 70

Console.WriteLine("C")

Case Else

Console.WriteLine("You fail")

End Select

Программисты с опытом работы на С и Java, обратите внимание — команда break не нужна, поскольку выполняется только одна секция Case. Дискретные наборы значений перечисляются через запятую, а ключевое слово То позволяет задавать интервалы:

Select Case yourChoice

Case 1 To 9

' Порядок

Case -1. 0

' Неправильный ввод

End Select

 

GoTo

Говоря об управляющих конструкциях, нельзя обойти вниманием команду GoTo. Если перефразировать старую шутку, современные программисты делятся на три группы: те, кто не знает, как пользоваться GoTo, и знать не хочет; те, кто не знает, но переживает по этому поводу; и те, кто умеет ею пользоваться.

Частое использование GoTo приводит к многократным передачам управления и порождает «спагетти-код», который трудно читать и отлаживать. С другой стороны, в некоторые ситуациях применение GoTo делает программу более понятной и логичной — например, если в какой-то ситуации потребовалось выйти сразу из нескольких вложенных циклов. Команда Exit для этого не подходит, поскольку она завершает только текущий цикл.

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

Чтобы воспользоваться командой GoTo в VB .NET, необходимо присвоить метку соответствующей строке. Метка начинается в первой позиции строки, ее первым символом является буква, а последним — двоеточие. Старайтесь присваивать меткам содержательные имена. Пример:

Bad-Input:

' Фрагмент, выполняемый при переходе

Предположим, в нашей программе данные вводятся во вложенном цикле For. Чтобы завершить ввод, пользователь вводит ZZZ :

SubMain()

Dim getData As String

Dim i, j As Integer

For i = 1 To 10

For j = 1 To 100

Console.Write("Type the data, hit the Enter key between " & _

"ZZZ to end: ") getData = Console. ReadLine()

If getData = "ZZZ" Then

Goto Bad Input Else

' Обработка данных

End If

Next j

Next i

Exit Sub

BadInput:

Console.WriteLine("Data entry ended at user request")

Console. ReadLine()

End Sub

Выходить из вложенного цикла командой Exit For неудобно — нам пришлось бы писать дополнительный код для выхода из внешнего цикла. Обратите внимание: команда Exi t Sub предотвращает передачу управления помеченному коду после завершения обоих циклов.

 

Логические операторы

Начиная с бета-версии 2 логические операторы (Not, And, Or и т. д.) работают на уровне двоичных разрядов, как и в прежних версиях VB. Допустим, у вас имеются два целых числа X и Y. Каждый бит результата X And Y равен 1 лишь в том случае, если равны 1 соответствующие биты обоих операндов; в противном случае бит результата равен нулю. Таким образом, при вычислении результата X And Y вычисляется каждый бит 32-разрядного целого числа. Пример:

X = 7 'В двоичном представлении = 0111

Y = 12 'В двоичном представлении = 1100

Выражение X And Y в двоичной системе равно 0100 (4 в десятичной системе), поскольку лишь во второй позиции оба бита равны 1. Остальные биты результата равны 0, поскольку в этих позициях хотя бы один из битов операндов равен 0. Этот способ позволяет проверить значения отдельных битов целого числа. Примеры:

(X And 1) = 1: проверить, установлен ли младший бит числа.

(X And 2) о 2: проверить, установлен ли предпоследний бит числа (поскольку в

двоичной системе число 2 представляется записью 10).

X And 255: младший байт числа (255 дес. = 11111111 дв.).

X And 65280: старший байт числа (65280 дес. = 1111111100000000 дв.).

Значение, предназначенное для проверки отдельных битов числа, называется маской (mask).

 

Массивы

В VB .NET имена массивов должны подчиняться тем же правилам, что и имена переменных. Ссылка на элемент массива выглядит как имя массива, за которым в круглых скобках указывается индекс.

Массивы VB .NET во многом отличаются от массивов VB6. Одни изменения видны сразу, другие не столь очевидны. Наиболее заметные изменения перечислены ниже.

  • Индексация-элементов в массивах начинается с 0. На момент написания книги ключевое слово То не поддерживалось — будем надеяться, что оно еще вернется!

    Начиная с бета-версии 2 объявление 01m stri ngLi st(7) создает массив из восьми элементов с индексами от 0 до 7. Поскольку в VB .NET индексация всегда начинается с нуля, третий элемент массива обозначается stri ngList(2), а предшествующие элементы обозначаются stringList(0) и stringList(l).

  • Все массивы VB .NET являются динамическими. Во время работы программы их можно переобъявить с новым размером при помощи команд ReDim (с потерей текущего содержимого) и ReDim Preserve (с сохранением текущего содержимого). Пример:

    Dim x() As Single

    ReDim x(20) ' Начиная с бета-версии 2. создает массив из 21 элемента

    ReDim Preserve x(50) ' 21 элемент сохраняется в массиве.

Команда ReDim не позволяет изменять тип массива; также не допускается использование ReDim при объявлении. Перед вызовом ReDim массив должен быть объявлен при помощи Dim или аналогичной команды.

  • Массивы могут инициализироваться при объявлении, как показывает следующий пример:

Dim weekend() As String = {Saturday. Sunday}

Менее очевидные изменения обусловлены тем, что массивы VB .NET являются экземплярами класса Array. Подробности будут рассмотрены в главе 4, а пока достаточно указать, что это позволяет выполнять операции с массивами вызовом методов класса Array. Ниже продемонстрирован пример сортировки массива методом Sort:

Sub Main()

Dim stuff() As Integer = (9. 7, 5, 4, 2. 1, -37, 6}

Array.Sort(stuff)

Dim i As Integer

For i = 0 To UBound(stuff)

Console.WriteLine(stuff(i))

Next

Console. ReadLine()

End Sub

Программа выводит массив, отсортированный с применением чрезвычайно эффективного алгоритма «быстрой сортировки».

VB.NET наследует от .NET Framework некоторые очень полезные структуры данных, возможности которых выходят далеко за рамки обычных массивов. На фоне этих структур коллекции VB5 и последующих версий выглядят примитивно. В частности, списковые массивы (с динамически изменяемыми размерами) и ассоциативные массивы (с доступом к данным по ключу) часто оказываются удобнее обычных массивов. Многие из новых структур данных рассматриваются в главах 5 и 6.

 

Массивы с индексацией элементов в заданном интервале

Утверждение о том, что индексация массивов всегда начинается с 0, не совсем точно. Теоретически можно определять массивы с заданной верхней и нижней границей индекса, но из-за неудобного синтаксиса и снижения быстродействия вряд ли вам захочется это делать. В следующем фрагменте создается массив с индексацией элементов от 1995 до 2002:

Sub Main()

Dim anArray As Array

Dim i As Integer

Dim i(0) As Integer

Dim lowerBounds(0) As Integer

i(O) = 7

lowerBounds(0) = 1995 ' Создать массив с индексами 1995 - 2002

аnАrrау = Array.CreateInstance(GetType(System.Int32). 1. lowerBounds) anArray.SetValue(200000, 1995) anArray.SetValue(1000000. 2001)

Console.WriteLine("The entry in position 1995 is " & _ (anArray.GetValue(1995).ToString))

Console.WriteLine("The entry in position 2002 is " & _ (anArray.GetValue(2001).ToString))

Console. ReadLine()

End Sub

Присваивание выполняется методом SetValue (значение,индекс), а чтение — методом GetValue(индекс). Но если массив создается подобным образом в режиме жесткой проверки типов, вам придется позаботиться о том, чтобы присваиваемое значение было преобразовано к правильному типу!

 

Назад Начало Вперед