原来C语言计算的数只要低过4个字节就要整型提升!

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个字节。

 

 好了,今天上午的学习到此结束!

猜你喜欢

转载自blog.csdn.net/xingyuncao520025/article/details/131241439