操作符详解2(一)+https://developer.aliyun.com/article/1520146?spm=a2c6h.13148508.setting.14.5a334f0ewLfWrY
2.算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
1. long double
2. double
3. float
4.unsigned long int
5.long int
6.unsigned int
7.int
如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外一个操作数的类型后执行运算。
即向上转换
三、问题表达式解析
1.表达式1
表达式的求值部分由操作符的优先级决定。
a*b + c*d + e+f
表达式1在计算的时候,由于*比+的优先级高,只能保证*的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行。
所以表达式的计算机顺序就可能是:
1 a*b
2 c+d
3 a*b + c*d
4 e+f
5 a*b + c*d + e*f
或者
1 a*b
2 c*d
3 e*f
4 a*b+c*d
5 a*b + c*d+ e*f
2.表达式2
c + -- c ;
同上,操作符的优先级只能决定自减﹣﹣的运算在+的运算的前面,但是我们并没有办法得知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
3.表达式3
int main() int i =10; i=i-- - --i*( i = -3)+ i++ + ++i; printf("i =%d\n", i); return 0;
表达式3在不同编译器中测试结果:非法表达式程序的结果
4.表达式4
int fun() { static int count=1; return ++count; } int main() { int answer; answer= fun()- fun()* fun(); printf( "%d\n", answer); return 0; }
上述代码
answer = fun()- fun() * fun();
中我们只能通过操作符的优先级得知:先算乘法,再算减法。
函数的调用先后顺序无法通过操作符的优先级确定。
5.表达式5
int main() { int i =1; int ret=(++i)+(++i)+(++i); printf("%d\n",ret); printf("%d\n",i); return 0; }
VS2022编译结果:
gcc编译结果:
6.总结
即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在潜在风险的,建议不要写出特别负责的表达式。