首页 > 解决方案 > 一元运算符的优先级是否高于强制转换表达式?

问题描述

我一直在通过着名的书籍c Premier plus 6th edition学习 C ,我对一元运算符的优先级和强制转换表达式有些困惑。

我在这里得到了这本书的 pdf 版本,本书下面提到的表格的位置是B: Reference Section Section II: C Operators--Table RS.II.1.

根据本书的表格,与一元运算符相比,强制转换表达式的优先级似乎较低。所以我对它进行了一个简单的测试,不知何故,它们似乎具有相同的优先级。下面是测试文件:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    /*we take advantage of the truncation when casting int to char(only remains the lower 8 bit of the int), if the cast executes first, the value is 0 so the final output is 1. Conversely, we get 0 as the final result.*/
    int test = 512;
    printf("test1-1 is %d\n",!(char)test); /*test1-1 is 1*/
    printf("test1-2 is %d\n",(char)!test); /*test1-2 is 0*/

    getchar();
    return 0;
}

在这个测试文件中,我选择一元运算符 作为代表。当然,还有其他一元运算符,但它们都有充分的理由不参与此测试:

这是我的环境设置:gcc 版本: gcc (tdm-1) 5.1.0 操作系统:windows7

我添加了命令选项,如-std=c90, -std=c99, -std=c11,它们都产生与测试文件中的注释完全相同的输出。这很奇怪,所以我求助于 C11 标准文档,相关信息在这里。所以这里的信息:

1.语法规定表达式求值中运算符的优先级,与本小节主要小节的顺序相同,最高优先级在前。

2.例外是强制转换表达式(6.5.4)作为一元运算符的操作数和......

这解释了很多,但行为是相同的,就好像它们共享相同的优先级一样。那么为什么不把它们放在一起以避免误导呢?只是因为强制转换表达式不属于一元运算符,并且为了保持 toc 的干净所以我们必须给强制转换表达式不同的优先级?这有点强迫症。

标签: ccastingoperator-precedenceunary-operator

解决方案


让我们关注您在测试中分析的运算符。逻辑非!运算符和强制转换运算符(type) 确实具有相同的优先级。

正如您在此表中看到的,它们都有优先级#2
您需要了解正在发生的事情还需要考虑 关联性。关联性表示将评估具有相同优先级的运算符的顺序。
我们正在讨论的运算符具有从右到左的关联性。

为了清楚起见,我将复制您的测试:

int main(void)
{
    /*we take advantage of the truncation when casting int to char(only remains the lower 8 bit of the int), if the cast executes first, the value is 0 so the final output is 1. Conversely, we get 0 as the final result.*/
    int test = 512;
    printf("test1-1 is %d\n",!(char)test); /*test1-1 is 1*/
    printf("test1-2 is %d\n",(char)!test); /*test1-2 is 0*/

    getchar();
    return 0;
}
  1. !(char)test中,从右到左的关联性意味着首先执行强制转换。这导致值“适应”char大小,从而产生 value 0

    然后应用逻辑否定,得到值1

  2. (char)!test中,从右到左的结合性意味着首先执行逻辑否定。这导致价值!512,产生价值0

    然后你应用强制转换,再次产生值0

由于这些原因,您实际上得到了预期的结果。


推荐阅读