【问题标题】:Associativity and Precedence in CC中的关联性和优先级
【发布时间】:2012-01-02 04:37:48
【问题描述】:

i) if(0) 是什么意思?

每次我用它来测试我会得到什么输出时,它都会返回错误的部分。

它是否等同于 if(0 == 0),以防万一计算真正的部分。

ii) 逻辑非的结合性!从右到左。

链接:http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseNotesnode94.html

逻辑运算符链接中的第二个例子:

但是根据“包含单子 .NOT. 的两个子表达式首先被有效评估,因为最左边有两个,.NOT.A 首先完成,然后是 .NOT.E.”,左边NOT首先被评估,但第一个被评估的应该是右边的那个......???

【问题讨论】:

    标签: c operator-keyword operator-precedence associativity


    【解决方案1】:

    I) 在 C 中,0 为假,其他一切为真。所以使用if (0),条件总是为假,并且body永远不会被执行,因为0总是假的。

    if (0 == 0) 完全不同,因为 0 实际上等于 0,而表达式 0 == 0 的计算结果为真,所以 if 的主体被执行。

    II) 运算符的关联性决定了当多个具有相同优先级的运算符有歧义时会发生什么。例如,a - b - c 应该发生什么?应该首先评估b - c 还是a - b确实你以什么顺序执行它们,因为如果 a = 1、b = 2 和 c = 3,a - (b - c)2,但 (a - b) - c 是 -4。但是因为减法是左结合的,所以我们可以知道 a - b 将首先被计算,所以当 a = 1, b = 2, c = 3 时,a - b - c 的答案是 -4。

    话虽如此,我想不出逻辑非运算符的关联性很重要的情况,并且运算符的关联性并不能确定当它被运算符分隔时它将以什么顺序执行不同的优先级。

    【讨论】:

    • 问题是关于 C,而不是 C++。
    • @WTP 哎呀,我想我修好了。现在一切都还适用吗?
    • 不仅减法必须从左到右进行,同样优先级的算术运算符也必须从左到右进行逻辑计算。原因是操作数的默认提升。总和 1+UINT_MAX+1.0 将不同于 1+1.0+UINT_MAX。第一个总和计算为(1+UINT_MAX)+1.0,等于1.0。第二个计算为(1+1.0)+UINT_MAX,等于2+UINT_MAX 的双倍。如果 int 是 16 位的,您将分别得到 1.065537.0。如果整数是 32 位的,你会得到 1.04294967297.0。尝试使用您的编译器。
    • @user980411 我将“In C++”更改为“In C”并删除了“带有内在类型”
    • @Alex 我想我在回答中指出了“当你有来自相同优先级的多个运算符的歧义时”这一行,但如果它有歧义,请告诉我。
    【解决方案2】:

    i) 在 C 中,0 表示 false,因此 if(0) 将始终跳转到 else(如果有)。 它与if(0==0)(或简单的if(1))相反,它将起到真正的作用。

    【讨论】:

      【解决方案3】:

      if (0) 将谓词 0 评估为二进制值。 C 中的二进制值使用整数,其中零表示假,非零表示真。因此,0 将始终评估为 false。

      对于二元运算符,右结合或左结合决定了处理其他同等重要的运算符的顺序。考虑减法运算符:

      37 - 10 - 4
      

      - 的优先级相同,那么我们应该先评估哪个?好吧,- 是左关联的,所以我们这样做:

      (37 - 10) - 4 ==> (27) - 4 ==> 23
      

      如果- 运算符是右关联的,我们会这样做:

      37 - (10 - 4) ==> 37 - 6 ==> 31
      

      等式 (=) 是右结合的,因为我们可能将等式链接在一起。所以,如果我们看到

      // a and b are initialized to 0
      a = b = 45
      

      = 的优先级相同,因此我们从右到左评估并执行以下操作:

      a = (b = 45) // b receives 45
      a = 45       // a receives 45
      

      如果我们从左到右,我们会得到意想不到的结果:

      (a = b) = 45 // a receives 0
      b = 45       // b receives 45
      

      然而,对于一元运算符,排序只有在多个一元运算符影响同一个值时才有意义。例如,让我们这样做:

      char x = 0xFF
      bool y = !~x
      

      这些一元运算符是右结合的,所以我们这样做:

      !(~0xFF) ==> !(0x0) ==> true
      

      在您展示的示例中,影响AE 的否定运算符没有“同等优先级”,因为它们没有相同的操作数。因此,关联性不适用。

      【讨论】:

      • NOT 的关联性在en.wikipedia.org/wiki/… 中从右到左给出。这意味着如果两个运算符具有相同的优先级,最右边的将首先执行...?
      • @user980411 是的,但只有当它们没有被不同优先级的运算符分隔时,关联性才重要(我认为)。我不知道一元运算符的关联性在哪里很重要。
      • @user980411 右关联表示not 运算符与其右侧的项目关联。这就是为什么我们写!false 而不是false!。这并不意味着 !a + !b 必须在 a 之前评估 b
      • @RobertMartin 你确定这就是右关联的意思吗?例如,= 运算符也是右关联的。
      • 我所说的仅适用于一元运算符。我将更新我的答案以包括二元运算符的右关联。
      猜你喜欢
      • 2020-10-20
      • 2012-08-13
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多