一、表达式求值
1.1整型提升
C语言中整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
如何进行整型提升呢?
1. 有符号整数提升是按照变量的数据类型的符号位来提升的。
2. 无符号整数提升,高位补0。
负数的整型提升:
char c1 = -1;
变量c1的⼆进制位(补码)中只有8个比特位:1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:11111111111111111111111111111111
正数的整型提升:
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:00000000000000000000000000000001
1.2算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外一个操作数的类型后执行运算。
1.3问题表达式
例如a*b+c*d+e*f
我们只能保证*比+的优先级高,所以他的计算顺序可能是:
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
如果遇到别的表达式,那么答案就可能产生歧义,例如:
c + --c;
我们只知道自减--的运算早+的运算之前,但我们并不知道+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的。
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
在不同编译器中,答案并不相同。