跳转至

运算符

原文: https://zetcode.com/lang/visualbasic/operators/

在 Visual Basic 教程的这一部分中,我们将讨论运算符。

运算符是特殊符号,表示已执行某个过程。 编程语言的运算符来自数学。 程序员处理数据。 运算符用于处理数据。

我们有几种类型的运算符:

  • 算术运算符
  • 布尔运算符
  • 关系运算符
  • 按位运算符

一个运算符可以有一个或两个操作数。 操作数是运算符的输入(参数)之一。 仅使用一个操作数的那些运算符称为一元运算符。 那些使用两个操作数的对象称为二进制运算符。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine(2)
        Console.WriteLine(-2)
        Console.WriteLine(2+2)
        Console.WriteLine(2-2)

    End Sub

End Module

+和-可以是加减运算符,也可以是一元符号运算符。 这取决于实际情况。

Option Strict On

Module Example

    Dim a As Byte

    Sub Main()

        a = 1
        Console.WriteLine(-a)    ' Prints -1
        Console.WriteLine(-(-a)) ' Prints 1

    End Sub

End Module

加号可以用来表示我们有一个正数。 但是它通常不被使用。 减号更改值的符号。

Option Strict On

Module Example

    Dim a As Byte
    Dim b As Byte

    Sub Main()

        a = 3 * 3
        b = 2 + 2   

        Console.WriteLine(a) ' Prints 9
        Console.WriteLine(b) ' Print 4

    End Sub

End Module

乘法和加法运算符是二进制运算符的示例。 它们与两个操作数一起使用。

赋值运算符

赋值运算符=将值赋给变量。 variable是值的占位符。 在数学中,=运算符具有不同的含义。 在等式中,=运算符是一个相等运算符。 等式的左侧等于右侧。

x = 1
Console.WriteLine(x) ' Prints 1

在这里,我们为x变量分配一个数字。

x = x + 1
Console.WriteLine(x)

先前的表达式在数学上没有意义。 但这在编程中是合法的。 该表达式将x变量加 1。 右边等于 2,并且 2 分配给x

3 = x

此代码示例导致语法错误。 我们无法为字面值分配值。

算术运算符

下表是 Visual Basic 中的算术运算符表。

符号 名称
+ 加法
- 减法
* 乘法
/ 除法
\ 整数除法
Mod 模数
^ 求幂

以下示例显示了算术运算。

Option Strict On

Module Example

    Dim a As Byte
    Dim b As Byte
    Dim c As Byte

    Dim add As Byte
    Dim sb As Byte
    Dim mult As Byte
    Dim div As Byte

    Sub Main()

        a = 10
        b = 11
        c = 12

        add = a + b + c
        sb = c - a
        mult = a * b
        div = CType(c / 3, Byte)

        Console.WriteLine(add)
        Console.WriteLine(sb)
        Console.WriteLine(mult)
        Console.WriteLine(div)

    End Sub

End Module

在前面的示例中,我们使用加,减,乘和除运算。 这些都是数学所熟悉的。

$ ./arithmetic.exe 
33
2
110
4

示例的输出。

接下来,我们将说明正态除法和整数除法之间的区别。

Option Strict On

Module Example

    Dim a As Single = 5
    Dim b As Single = 2
    Dim c As Single

    Sub Main()

        c = 5 / 2 
        Console.WriteLine(c)
        c = 5 \ 2
        Console.WriteLine(c)

    End Sub

End Module

在前面的示例中,我们使用普通和整数除法运算符对两个数进行除法。 Visual Basic 有两个不同的除法运算符。

Dim a As Single = 5

我们使用浮点数据类型。

c = 5 / 2 
Console.WriteLine(c)

这是“正常”的分割操作。 它返回 2.5,如预期的那样。

c = 5 \ 2
Console.WriteLine(c)

这是整数除法。 此操作的结果始终为整数。 c变量的值为 2。

$ ./division.exe 
2.5
2

division.exe程序的结果。

我们将提到的最后两个运算符是模运算符和幂运算符。

Console.WriteLine(9 Mod 4) ' Prints 1

Mod运算符称为模运算符。 它找到一个数除以另一个的余数。 9 Mod 4,9 模 4 为 1,因为 4 两次乘以 9,余数为 1。例如,当我们要检查素数时,模运算符会很方便。

最后,我们将提到求幂运算符。

Console.WriteLine(9 ^ 2) ' Prints 81

9 ^ 2 = 9 * 9 = 81

连接字符串

在 Visual Basic 中,我们有两个用于字符串连接的运算符。 加号+运算符和&和号运算符。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine("Return " & "of " & "the king")
        Console.WriteLine("Return " + "of " + "the king")

    End Sub

End Module

我们使用两个运算符将三个字符串连接在一起。

$ ./concatstrings.exe 
Return of the king
Return of the king

这就是我们得到的。 两种情况的结果相同。

布尔运算符

在 Visual Basic 中,我们具有以下逻辑运算符。 布尔运算符也称为逻辑运算符。

符号 名称
And 逻辑与
AndAlso 短路与
Or 逻辑或
OrElse 短路或
Xor 逻辑异或
Not 否定

布尔运算符用于处理真值。

Option Strict On

Module Example

    Dim x As Byte = 3
    Dim y As Byte = 8

    Sub Main()

        Console.WriteLine(x = y) 
        Console.WriteLine(y > x)

        If (y > x)
            Console.WriteLine("y is greater than x")
        End If

    End Sub

End Module

许多表达式导致布尔值。 布尔值用于条件语句中。

Console.WriteLine(x = y) 
Console.WriteLine(y > x)

关系运算符始终导致布尔值。 这两行显示FalseTrue

If (y > x)
    Console.WriteLine("y is greater than x")
End If

仅在满足括号内的条件时才执行If语句的主体。 x > y返回True,因此消息"y大于x"被打印到终端。

Option Strict On

Module Example

    Dim a As Boolean
    Dim b As Boolean
    Dim c As Boolean
    Dim d As Boolean

    Sub Main()

        a = (True And True)
        b = (True And False)
        c = (False And True)
        d = (False And False)

        Console.WriteLine(a)
        Console.WriteLine(b)
        Console.WriteLine(c)
        Console.WriteLine(d)

    End Sub

End Module

示例显示了逻辑And运算符。 仅当两个操作数均为True时,它的求值结果为True

$ ./andop.exe 
True
False
False
False

如果正好一个操作数为True,则逻辑Xor运算符的计算结果为True

Option Strict On

Module Example

    Dim a As Boolean
    Dim b As Boolean
    Dim c As Boolean
    Dim d As Boolean

    Sub Main

        a = (True Xor True)
        b = (True Xor False)
        c = (False Xor True)
        d = (False Xor False)

        Console.WriteLine(a)
        Console.WriteLine(b)
        Console.WriteLine(c)
        Console.WriteLine(d)

    End Sub

End Module

如果两个操作数均为True或均为False,则逻辑Xor的计算结果为False

$ ./xorop.exe 
False
True
True
False

如果两个操作数中的任何一个为True,则逻辑Or运算符的计算结果为True

Option Strict On

Module Example

    Sub Main()

        Dim a As Boolean = True Or True
        Dim b As Boolean = True Or False
        Dim c As Boolean = False Or True
        Dim d As Boolean = False Or False

        Console.WriteLine(a)
        Console.WriteLine(b)
        Console.WriteLine(c)
        Console.WriteLine(d)

    End Sub

End Module

如果运算符的任一侧为 True,则运算结果为 True。

$ ./orop.exe 
True
True
True
False

否定运算符Not设为True FalseFalse True

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine(Not True)
        Console.WriteLine(Not False)
        Console.WriteLine(Not (4 < 3))

    End Sub

End Module

该示例显示了否定运算符的作用。

$ ./negation.exe 
False
True
True

AndAlsoOrElse运算符经过短路求值。 短路求值意味着仅当第一个参数不足以确定表达式的值时才求值第二个参数:当And的第一个参数求值为false时,总值必须为false; 并且当Or的第一个参数计算为true时,总值必须为true。 (维基百科)短路求值主要用于提高性能。

一个例子可以使这一点更加清楚。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine("Short circuit")
        If (one AndAlso two)
            Console.WriteLine("Pass")
        End If

        Console.WriteLine("#############")
        If (one And two)
            Console.WriteLine("Pass")
        End If

    End Sub

Function one As Boolean
    Console.WriteLine("Inside one")
    Return False
End Function

Function two As Boolean
    Console.WriteLine("Inside two")
    Return True
End Function

End Module

在示例中,我们有两个函数。 函数与子例程不同,返回值。 这是它们之间的主要区别。

If (one AndAlso two)
    Console.WriteLine("Pass")
End If

一个函数返回False。 短路AndAlso不求值第二功能。 没有必要。 一旦操作数为False,逻辑结论的结果始终为False。 控制台上仅打印"Inside one"

Console.WriteLine("#############")
If (one And two)
    Console.WriteLine("Pass")
End If

在第二种情况下,我们使用And。 在这种情况下,两个函数都被调用。 即使表达式的结果不是必需的。

$ ./shorcircuit.exe 
Short circuit
Inside one
#############
Inside one
Inside two

shorcircuit.exe程序的结果。

关系运算符

关系运算符用于比较值。 这些运算符总是产生布尔值。

符号 含义
< 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于
<> 不等于
Is 比较引用

关系运算符也称为比较运算符。

Console.WriteLine(3 < 4) ' Prints True
Console.WriteLine(3 = 4) ' Prints False
Console.WriteLine(4 >= 3) ' Prints True

正如我们已经提到的,关系运算符返回布尔值。 请注意,在 Visual Basic 中,比较运算符为=。 不像受 C 和 C 影响的语言那样==

注意,关系运算符不限于数字。 我们也可以将它们用于其他对象。 尽管它们可能并不总是有意义的。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine("six" = "six") ' Prints True
        ' Console.WriteLine("a" > 6) this would throw
                                     ' an exception 
        Console.WriteLine("a" < "b") ' Prints True

    End Sub

End Module

我们也可以比较字符串对象。 字符串上下文中的比较运算符比较字符的排序顺序。

Console.WriteLine("a" < "b") ' Prints True

这里到底发生了什么? 计算机不知道字符或字符串。 对于他们来说,一切都只是数字。 字符是存储在特定表中的特殊数字。 类似于 ASCII。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine("a" < "b")

        Console.WriteLine("a is: {0}",  Asc("a"))
        Console.WriteLine("b is: {0}",  Asc("b"))

    End Sub

End Module

在内部,a 和 b 字符是数字。 因此,当我们比较两个字符时,我们将比较它们的存储数字。 内置的Asc函数返回单个字符的 ASCII 值。

$ ./compare.exe 
True
a is: 97
b is: 98

实际上,我们将 97 和 98 这两个数字进行比较。

Console.WriteLine("ab" > "aa") ' Prints True

假设我们有一个包含更多字符的字符串。 如果前几个字符相等,我们将比较下一个字符。 在我们的情况下,第二个位置的 b 字符的值比 a 字符大。 这就是为什么"ab"字符串大于"aa"字符串的原因。 当然,以这种方式比较字符串没有多大意义。 但这在技术上是可能的。

最后,我们将提到Is运算符。 运算符检查两个对象引用是否引用同一对象。 它不执行值比较。

Option Strict On

Module Example

    Sub Main()

        Dim o1 As Object = New Object
        Dim o2 As Object = New Object
        Dim o3 As Object 

        o3 = o2

        Console.WriteLine(o1 Is o2)
        Console.WriteLine(o3 Is o2)

    End Sub

End Module

我们创建三个对象,并将它们与Is运算符进行比较。

Dim o1 As Object = New Object
Dim o2 As Object = New Object

我们声明并初始化两个Object实例。 Object类是.NET 框架中所有类的基类。 我们将在以后更详细地描述它。

Dim o3 As Object 

仅声明第三个变量。

o3 = o2

o3现在引用o2对象。 它们是对同一对象的两个引用。

Console.WriteLine(o1 Is o2)
Console.WriteLine(o3 Is o2)

在第一种情况下,我们得到Falseo1o2是两个不同的对象。 在第二种情况下,我们得到Trueo3o2指的是同一对象。

按位运算符

小数对人类是自然的。 二进制数是计算机固有的。 二进制,八进制,十进制或十六进制符号仅是相同数字的符号。 按位运算符使用二进制数的位。 像 Visual Basic 这样的高级语言很少使用按位运算符。

符号 含义
Not 按位取反
Xor 按位异或
And 按位与
Or 按位或

按位取反运算符分别将 1 更改为 0,将 0 更改为 1。

Console.WriteLine(Not 7)  ' Prints -8
Console.WriteLine(Not -8) ' Prints 7

运算符恢复数字 7 的所有位。这些位之一还确定数字是否为负。 如果我们再一次对所有位取反,我们将再次得到 7。

按位,运算符在两个数字之间进行逐位比较。 仅当操作数中的两个对应位均为 1 时,位位置的结果才为 1。

      00110
  And 00011
   =  00010

第一个数字是二进制符号 6,第二个数字是 3,结果是 2。

Console.WriteLine(6 And 3) ' Prints 2
Console.WriteLine(3 And 6) ' Prints 2

按位或运算符在两个数字之间进行逐位比较。 如果操作数中的任何对应位为 1,则位位置的结果为 1。

     00110
  Or 00011
   = 00111

结果为00110或十进制 7。

Console.WriteLine(6 Or 3) ' Prints 7
Console.WriteLine(3 Or 6) ' Prints 7

按位互斥或运算符在两个数字之间进行逐位比较。 如果操作数中对应位中的一个或另一个(但不是全部)为 1,则位位置的结果为 1。

      00110
  Xor 00011
   =  00101

结果为00101或十进制 5。

Console.WriteLine(6 Xor 3) ' Prints 5

复合赋值运算符

复合赋值运算符由两个运算符组成。 他们是速记员。

Option Strict On

Module Example

    Dim a As Integer

    Sub Main

        a = 1
        a = a + 1
        Console.WriteLine(a) ' Prints 2

        a += 1
        Console.WriteLine(a) ' Prints 3

    End Sub

End Module

+=复合运算符是这些速记运算符之一。 它们比完整的表达式可读性差,但是经验丰富的程序员经常使用它们。

其他复合运算符是:

-=   *=   \=   /=   &=  ^= 

运算符优先级

运算符优先级告诉我们首先求值哪个运算符。 优先级对于避免表达式中的歧义是必要的。

以下表达式 28 或 40 的结果是什么?

 3 + 5 * 5

像数学中一样,乘法运算符的优先级高于加法运算符。 结果是 28。

(3 + 5) * 5

要更改求值的顺序,可以使用括号。 括号内的表达式始终首先被求值。

下面的列表显示了按优先级排序的常见 Visual Basic 运算符(优先级最高):

运算符 描述
^ 求幂
+ - 一元加减
* / 乘法,浮点除法
\ 整数除法
Mod 模数
+ - 加法,减法,字符串连接
& 字符串连接
<< >> 算术移位
= <> < > >= <= Is IsNot Like TypeOf Is 所有比较运算符
Not 否定
And AndAlso
Or OrElse
Xor 异或

列表中同一行上的运算符具有相同的优先级。

Option Strict On

Module Example

    Sub Main()

        Console.WriteLine(3 + 5 * 5)
        Console.WriteLine((3 + 5) * 5)

        Console.WriteLine(Not True Or True)
        Console.WriteLine(Not (True Or True))

    End Sub

End Module

在此代码示例中,我们显示一些常见的表达式。 每个表达式的结果取决于优先级。

Console.WriteLine(3 + 5 * 5)

该行打印 28。乘法运算符的优先级高于加法。 首先计算5*5的乘积。 然后添加 3。

Console.WriteLine(Not True Or True)

在这种情况下,否定运算符具有更高的优先级。 首先,第一个True值被否定为False,然后Or运算符组合FalseTrue,最后得到True

$ ./precedence.exe 
28
40
True
False

关联性

有时,优先级不能令人满意地确定表达式的结果。 还有另一个规则称为关联性。 运算符的关联性确定优先级与相同的运算符的求值顺序。

9 / 3 * 3

这种表达的结果是什么? 9 还是 1? 乘法,删除和模运算符从左到右关联。 因此,该表达式的计算方式为:(9 / 3) * 3,结果为 9。

算术,布尔,关系和按位运算符都是左右关联的。

另一方面,赋值运算符是正确关联的。

a = b = c = d = 0
Console.WriteLine("{0} {1} {2} {3}", a, b, c, d) ' Prints 0 0 0 0 

如果关联从左到右,则以前的表达式将不可能。

复合赋值运算符从右到左关联。

j = 0
j *= 3 + 1
Console.WriteLine(j)  

您可能期望结果为 1。但是实际结果为 0。由于有关联性。 首先求值右边的表达式,然后应用复合赋值运算符。

AddressOf运算符

AddressOf运算符创建一个指向另一个函数的函数委托。 委托是类型安全的函数指针,它们用于调用其他对象的方法。

Option Strict On

Module Example

    Delegate Sub Display

    Dim msg As New Display(AddressOf Message1)

    Sub Main()

        msg.Invoke()
        msg = New Display(AddressOf Message2)
        msg.Invoke()

    End Sub

    Sub Message1()
        Console.WriteLine("This is message 1")
    End Sub

    Sub Message2()
        Console.WriteLine("This is message 2")
    End Sub

End Module

在代码示例中,我们使用AddressOf运算符指向两个不同的子例程。

Delegate Sub Display

我们需要声明一个委托。

Dim msg As New Display(AddressOf Message1)

委托使用AddressOf运算符获取子例程的地址。 现在,我们有一个指向Message1()子例程的类型安全指针。

msg.Invoke()

Invoke()方法调用委托指向的方法。

msg = New Display(AddressOf Message2)
msg.Invoke()

现在,我们为委托人提供另一个子例程的地址。

$ ./addressof.exe 
This is message 1
This is message 2

两条消息都打印到控制台。

在 Visual Basic 教程的这一部分中,我们介绍了运算符。



回到顶部