运营商如何运作?

时间:2009-08-31 06:48:35

标签: programming-languages

我想知道运营商如何在计算机内部工作?

并且有许多运算符用于执行许多任务,例如“+”用于添加两个数字以及在java中连接两个字符串..那么,它如何区分这些类型的任务?

7 个答案:

答案 0 :(得分:3)

你真正要问的是"how do compilers work?" - 运算符是编译器必须解析的一种标记,并且与其他类型的标记(如方法)没有根本的区别 - 实际上,在允许您定义的语言中你自己的运算符,定义通常看起来像一个方法定义。

唯一的区别是运营商可以拥有infix syntax并且需要优先级规则 - 但这只意味着parsing rules比其他令牌更复杂一些。事实上,最后一个链接可能是您问题的最直接和具体的答案。

答案 1 :(得分:1)

编译器知道操作数的数据类型。如果它看到 2+3 这样的表达式,它将确定两个操作数(即 2 3 )是整数,因此编译器将生成执行整数加法的可执行代码。如果表达式是 "Hey, " + "Bob!" ,编译器会看到操作数是字符串,如果语言支持字符串添加(例如在Java中),它将生成执行字符串连接的代码。 / p>

还有一些语言可以在程序运行时决定。在某些情况下,要完成一个运行时,因为编译器在编译时没有足够的信息来决定这个“+”运算符应该做什么。

答案 2 :(得分:0)

通过使用语言解析器,源代码将转换为已编译的代码或内部表示,然后执行。

答案 3 :(得分:0)

计算机语言的语法经过精心设计,以便编译器/解释器可以决定代码对运算符的使用。

根据定义,正确编写的语法代码永远不会含糊不清。

当编译器说'语法错误'时,它告诉你代码是不明确的。

答案 4 :(得分:0)

运算符的工作方式与带参数的函数非常相似。或者,在现代面向对象语言中,就像带有参数的对象上的方法一样。如果你看一下C ++中的方法重载技术,你可以看到这个问题。所以数字+运算符是 - 在一种伪代码中 - 就像这样:

function integer.+(b: integer) {
   return ADD self, b;
}

其余的是语法糖。

你有没有带有后缀表示法的惠普计算器?用这些术语来思考它。因此编译器会将a + b转换为(+ a b)或面向a。+(b)的对象。

编译器从两个操作数派生操作的类型(加法,连接),证明类型兼容性(将整数添加到float ok,concat整数和字符串取决于语言)。

然后将代码转换为内部表示和机器代码。

答案 5 :(得分:0)

它基于(获取此)您使用的运算符来区分任务。解析代码时,解析器/编译器会找到运算符并决定如何处理它周围的事物。如果+用于加法和连接,则取决于提供给它的参数。语言决定在混合时要做什么,例如,如果“4”+ 5等于“45”或9。

此外,运营商优先。也就是说,某些运营商的评估比其他运营商更快。有点像你在数学中学到的操作顺序。例如,+和 - 运算符的优先级通常低于*和/(乘法和除法)运算符(即,乘法运算将在加法运算之前发生)。这就是4 * 5 + 2将等于22而不是28的原因。您可以找到一个运算符优先级表here.这适用于C语言,但对于大多数其他语言应该类似。

还有运营商关联性。这(基本上)是评估相同类型的运算符的顺序。你习惯的大部分都将保持联想。例如:

4 * 5 * 6 * 7

这是左联想的,意思是:

((4 * 5) * 6) * 7

如果有两个或多个具有相同优先级的运算符“连续”(如示例中所示),则将从左到右对它们进行求值。也就是说,首先是4 * 5,然后是20 * 6,然后是120 * 7.右关联运算符的一个例子是指数运算符:

 4 ^ 5 ^ 6 ^ 7

这变为

 4 ^ (5 ^ (6 ^ 7))

这些从右到左进行评估。如果指数运算符是左关联的,那么这将产生错误的答案。

将关联性视为“括号内的哪一侧”。它们在左侧是左侧关联,右侧是右侧关联。

same link包含每个运营商的关联性。同样,它适用于C语言,但对于您将使用的大多数其他语言,它应该几乎相同。

答案 6 :(得分:0)

包含“a + b *(c-d)”等运算符的字符串是一个表达式。编译器解析表达式并创建一个称为抽象语法字符串的中间结构:

          +
         / \
        a   *
           / \
          b   +
             / \
            c   d

借助语法树,可以计算表达式。叶子的类型(a,b,c,d)决定了需要哪种操作。此信息用于表达表达式(对于解释器)或创建机器代码:

get c  ; get variable c in a register
add d  ; add variable d
mul b  ; multiply with variable b
add a  ; add variable a
store restult ; store the restult

有时会添加隐式操作,例如类型转换。大多数编译器都会添加一些优化。