一元运算符的优先级是否高于强制转换表达式?
Do unary operators have higher precedence than the cast expression?
我一直在通过名著c premier plus the 6th edition学习C,我对一元运算符和转换表达式的优先级。
I get the pdf version of the book here,本书下面提到的table的位置是B: Reference Section Section II: C Operators--Table RS.II.1
.
根据本书的table,与一元运算符相比,强制转换表达式的优先级似乎较低。所以我 运行 对它进行了一个简单的测试,不知何故它们似乎具有相同的优先级。下面是测试文件:
#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;
}
在这个测试文件中,我选择一元运算符!作为表示。当然,还有其他一元运算符,但它们都有充分的理由不参与此测试:
- ++、-- 和 &:它们只能使用左值作为 ope运行d,这不是强制转换表达式可以为
ar运行ge 的东西
- -、+ 和 ~:我们可以声明一个 long long int 变量并将其转换为 int,也许截断可以告诉我们一些事情。不幸的是,我们从中找不到任何东西,做一些基本的数学运算,你会发现是一元运算符先执行还是强制转换先执行,反正它不会改变输出。
- 其他人:对我来说毫无意义
这是我的环境设置:
gcc 版本:gcc (tdm-1) 5.1.0
OS: windows7
我添加了 -std=c90
、-std=c99
、-std=c11
等命令选项,它们都产生与测试文件中的注释完全相同的输出。太奇怪了,所以我转向C11标准文档寻求帮助,相关信息是here。所以这是信息:
1.The syntax specifies the precedence of operators in the evaluation of an expression, which is the same
as the order of the major subclauses of this subclause, highest precedence first.
2.The exceptions are cast expressions (6.5.4) as operands of unary operators and ...
这解释了很多,但行为是相同的,就好像它们具有相同的优先级一样。那么为什么不把它们放在一起避免误导呢?
仅仅因为 cast 表达式不属于一元运算符,并且为了保持 toc 干净所以我们必须给 cast 表达式不同的优先级?这有点强迫症。
让我们重点关注您在测试中分析的运算符。逻辑非 !
运算符和转换运算符 (type)
do 具有相同的优先级。
如您在 this table 中所见,它们都具有优先级 #2.
您需要了解正在发生的事情还需要考虑 关联性 。关联性表示对具有相同优先级的运算符进行求值的顺序。
我们正在考虑的运算符具有 Right-to-left 关联性。
为了清楚起见,我将复制您的测试:
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;
}
在!(char)test
中,right-to-left结合性表示先进行强制转换。这导致值“适应”char
大小,导致值 0
.
然后应用逻辑非,得到值 1
在(char)!test
中,right-to-left结合律表示先进行逻辑非。这导致值 !512
,导致值 0
.
然后应用转换,再次产生值 0
由于这些原因,您实际上得到了预期的结果。
我一直在通过名著c premier plus the 6th edition学习C,我对一元运算符和转换表达式的优先级。
I get the pdf version of the book here,本书下面提到的table的位置是B: Reference Section Section II: C Operators--Table RS.II.1
.
根据本书的table,与一元运算符相比,强制转换表达式的优先级似乎较低。所以我 运行 对它进行了一个简单的测试,不知何故它们似乎具有相同的优先级。下面是测试文件:
#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;
}
在这个测试文件中,我选择一元运算符!作为表示。当然,还有其他一元运算符,但它们都有充分的理由不参与此测试:
- ++、-- 和 &:它们只能使用左值作为 ope运行d,这不是强制转换表达式可以为 ar运行ge 的东西
- -、+ 和 ~:我们可以声明一个 long long int 变量并将其转换为 int,也许截断可以告诉我们一些事情。不幸的是,我们从中找不到任何东西,做一些基本的数学运算,你会发现是一元运算符先执行还是强制转换先执行,反正它不会改变输出。
- 其他人:对我来说毫无意义
这是我的环境设置:
gcc 版本:gcc (tdm-1) 5.1.0
OS: windows7
我添加了 -std=c90
、-std=c99
、-std=c11
等命令选项,它们都产生与测试文件中的注释完全相同的输出。太奇怪了,所以我转向C11标准文档寻求帮助,相关信息是here。所以这是信息:
1.The syntax specifies the precedence of operators in the evaluation of an expression, which is the same as the order of the major subclauses of this subclause, highest precedence first.
2.The exceptions are cast expressions (6.5.4) as operands of unary operators and ...
这解释了很多,但行为是相同的,就好像它们具有相同的优先级一样。那么为什么不把它们放在一起避免误导呢? 仅仅因为 cast 表达式不属于一元运算符,并且为了保持 toc 干净所以我们必须给 cast 表达式不同的优先级?这有点强迫症。
让我们重点关注您在测试中分析的运算符。逻辑非 !
运算符和转换运算符 (type)
do 具有相同的优先级。
如您在 this table 中所见,它们都具有优先级 #2.
您需要了解正在发生的事情还需要考虑 关联性 。关联性表示对具有相同优先级的运算符进行求值的顺序。
我们正在考虑的运算符具有 Right-to-left 关联性。
为了清楚起见,我将复制您的测试:
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;
}
在
!(char)test
中,right-to-left结合性表示先进行强制转换。这导致值“适应”char
大小,导致值0
.然后应用逻辑非,得到值
1
在
(char)!test
中,right-to-left结合律表示先进行逻辑非。这导致值!512
,导致值0
.然后应用转换,再次产生值
0
由于这些原因,您实际上得到了预期的结果。