C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换被称为整型提升。
比如:
char a = 3;
char b = 127;
char c = a + b;
printf("%d", c);
这个时候C的值是多少呢?你可能会想a=3,b=127,相加就是130,如果这么想就错了,计算机的计算可没有这么简单。先说一下计算结果c=-126.是不是感觉有些不可思议呢?下面就来剖析一下计算机的计算过程。
c=a+b,证明a和b都要参加运算的,由于a和b是char型只有一个字节,不足4个字节,所以要提升
a的存储是:0000 0011 这就是a在内存中存储的形式
b的存储是:0111 1111 这就是b在内存中存储的形式
a和b只有一个字节,还是有符号型的类型,所以提升的结果就是:
0000 0000 0000 0000 0000 0000 0000 0011 a整型提升
0000 0000 0000 0000 0000 0000 0111 1111 b整型提升
提升后就都是4个字节了,现在就可以计算a+b了,两个32位的二进制数相加的结果就是:
0000 0000 0000 0000 0000 0000 1000 0010 a和b相加的结果
这会要把结果存放到c中,发现c是char型的,只能存放1个字节,现在就要截断了。截断成1个字节
1000 0010 结果给c时发现是char型 要截断就变成了 1000 0010了
最后要打印整型的c,又需要cpu来计算,由于c是一个字节的char型,所以还要整型提升,
1000 0010 的整型提升就是补全符号位,结果为:
1111 1111 1111 1111 1111 1111 1000 0010 现在是c的补码 要 求c的反码(这个数减1)结果:
1111 1111 1111 1111 1111 1111 1000 0001 现在是c的反码 再求c的原码,除符号位取反,结果:
1000 0000 0000 0000 0000 0000 0111 1110 现在是c的原码,此时首位为1,证明是负数,后面的111 1110 的 十进制值是126, 加上负数 正好c的值就变成了 -126.
这就是这个简单的加法运算在计算机中的运算过程,看着简单,实则很麻烦的。
为了验证这个cpu运算是要把不足4字节的数都要整型提升列举了下面这个列子:
#include"stdio.h"
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if (a == 0xb6)
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c"); // 结果只打印了c
return 0;
}
结果只打印了c,证明a和b都被提升了,和原来的值不相等了。
咱么在通过下面的列子来辅证一下这个整型提升的结论:
int main()
{
char a = 1;
printf("%u\n", sizeof(a)); // 1 %u打印一个无符号数。
printf("%u\n", sizeof(+a)); // 4
printf("%u\n", sizeof(-a)); // 4
return 0;
}
上面的代码,第一个打印a的字节数是1,char类型就是1个字节没有错,
后面的+a和-a都是有运算符的,需要a参加运算,所以a就要整型提升了,结果打印的值就是4了。证明提升到了4个字节。
好了,今天上午的学习到此结束!