整型提升的意义:表达式的整型运算要在CPU的相应运算器件内执?,CPU内整型运算器(ALU)的操作数的字节?度?般就是int的字节?度,同时也是CPU的通?寄存器的?度。因此,即使两个char类型的相加,在CPU执?时实际上也要先转换为CPU内整型操作数的标准?度。 通?CPU(general-purpose CPU)是难以直接实现两个8?特字节直接相加运算(虽然机器指令中 可能有这种字节相加指令)。所以,表达式中各种?度可能?于int?度的整型值,都必须先转换为 int或unsigned int,然后才能送?CPU去执?运算
//负数的整形提升
char c1 = -1;
//变量c1的?进制位(补码)中只有8个?特位:
//1111111
//因为 char 为有符号的 char
//所以整形提升的时候,?位补充符号位,即为1
//提升之后的结果是:
//11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
//变量c2的?进制位(补码)中只有8个?特位:
//00000001
//因为 char 为有符号的 char
//所以整形提升的时候,?位补充符号位,即为0
//提升之后的结果是:
//00000000000000000000000000000001
//?符号整形提升,?位补0
案例1:
#include <stdio.h>
int main()
{
char c1 = 125;
//unsigned char c1=125;
//范围 -128~127
//0000 0000 0000 0000 0000 0000 0111 1101
//发生截断
//01111101 -c1
char c2 = 10;
//0000 0000 0000 0000 0000 0000 0000 1010
//00001010 -c2
char c3 = c1 + c2;
//0000 0000 0000 0000 0000 0000 0111 1101 有符号的char c1
//0000 0000 0000 0000 0000 0000 0000 1010 有符号的char c2
//0000 0000 0000 0000 0000 0000 1000 0111
//1000 0111 -c3
//补充符号位
//1111 1111 1111 1111 1111 1111 1000 0111 -补码
//1000 0000 0000 0000 0000 0000 0111 1001 -原码
//1+8+16+32+64
printf("%d\n", c3);//-121
return 0;
}
//表达式的求值部分由操作符的优先级决定。
//表达式1
a* b + c * d + e * f
表达式1在计算的时候,由于*比+的优先级高,只能保证*的计算是比+早,但是优先级斌不能决定第三个*比第一个+先执行。最好用()表达清楚的执行顺序。
//表达式2
c + --c;
同表达式1,操作符的优先级只能决定自减--在+的运算之前,但是我们不清楚+操作符的左操作数的获取在右操作数之前还是之后求职,结果是不可预测的,有歧义的
//表达式3
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
#include <sdtio.h>
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0;
}
//表达式5
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
//尝试在linux 环境gcc编译器,VS2013环境下都执?,看结果。
📕 即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯?的 计算路径,那这个表达式就是存在潜在?险的,建议不要写出特别负责的表达式。