表达式求值
表达式求值的顺序一部分是由操作符的优先级和综合性决定。有些表达式的操作数在求值的过程中可能需要转化为其他类型
一.隐式类型转换
1.整形提升
整形提升:表达式中的字符和短整型操作数在使用之前被转换为普通整形(转换short,char型)



// 无符号整形提升(unsigned char),高位补0
实例:
#include
int main()
{
char a = 3;
//3:00000000000000000000000000011
//由于在char型下,只有8个比特位,从后往前截取得a: 00000011
char b = 127;
//127:00000000000000000000001111111
//同上b:01111111
//正数的原码反码补码相同
char c = a + b;
///3: 00000000000000000000000000011
//127: 00000000000000000000001111111
//3+127 : 00000000000000000000010000010
//c:10000010
//c整形提升后:11111111111111111111111110000010,这是补码
//c原码: 10000000000000000000001111110 ———— -126
printf("%d\n",c);//打印时得求出原码
return 0;
}
注意:内存中存的是补码,内存中数字计算的是补码
printf("%d\n",c);//打印时得求出原码
实例
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb60000000;
if(a = 0xb6)//因为表达式中a是char类型,没达到一个整形大小,所以会整形提升
{
printf("a");//而当a整形提升后便不再是原来的值,所以不会打印
}
if(b = 0xb600)
{
printf("0xb600");//与上同理
}
if(c = 0xb60000000)
{
printf("0xb60000000");//由于c本来就是整形,不去提升
}
//仅打印c
return 0;
}
//c
int main()
{
char a = 1;
printf("%u\n",suzeof(a));// 1 仅计算a的大小
printf("%u\n",suzeof(+a));//4 +a表示参与运算,则需进行整形提升
printf("%u\n",suzeof(-a));//4 同上
return 0;
}
注意:c只要参与表达式运算就会发生整形提升
2.算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上表中排名较低,那么首先要转换为另外一个操作数的类型后,再执行运算。(向长/精度更高的的转换)

二.操作符属性
复杂操作符的求值有3个影响因素:
1.操作符的优先级(执行的先后)
2.操作符的结合性(运算的方向)
3.是否控制求值顺序(有"&&","||","?:","," 四种)
两个相邻的操作符先执行哪个?
取决于他们的优先级,如果两者的优先级相同,取决于他们的结合性
优先级和结合性表:
(从上到下优先级逐渐降低)
(L-R表示结合性从左向右,R-L表示从右向左,N/A表示无结合性)






在我们掌握操作符的属性后,能处理大多数的情况,但是还有一部分表达式是没办法确定唯一计算顺序的
例如:当c = 3时 c + --c //3+2 = 5 //2+2 = 4
操作符的优先级只能决定自减--的运算在+的运算的前面,但是不能决定+操作符的左操作数的获取在右操作数之前还是之后求值
(如果我们不能通过操作符确定为一的计算路径,这个表达式是有问题的)