浅谈截断和整型提升

截断定义

  截断:在c语言中进行变量赋值的时候,如果将字节多的数据类型赋给字节少的数据类型时,有一部分的数据就会没有空间存储,并且只能存放低位数据,这种情况就是截断。
  例如:

int i = 123;
char c = 'i';
c = i;

  当进行c=i赋值操作时,会发生截断。

整型提升定义

  整型提升:在c语言中整型算数运算总是至少以缺省整型类型的精度进行的,是短整型到更长整型时需要进行整型提升。

整型提升规则:
  本身的数据类型无符号补0,有符号补符号位。

截断和整型提升的练习

代码1

#include <stdio.h>
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

答案:a = -1, b = -1, c = 255
解析:
  正常来说定义一个整型是有符号的,因此,a和b是等价的表示的范围是-128~127,c是无符号类型,表示的范围是0-255。
  a的原码 10000000 00000000 00000000 00000001
  a的补码 11111111 11111111 11111111 11111111
  因为char类型最多表示8个位,因此从大类型到小类型会发生截断 11111111
  当输出的时候,会进行补位,11111111是有符号的,并且符号位位1,因此,高位补1,结果为 11111111 11111111 11111111 11111111,这个是结果是补码的形式,再转换回去,结果为-1。b和a语句本身就是等价的,所以结果是一样的。
  c的原码 10000000 00000000 00000000 00000001
  c的补码 11111111 11111111 11111111 11111111
  发生截断 11111111
  因为是无符号类型,最高位补0,结果为 00000000 00000000 00000000 11111111 ,最终结果为255。

代码2

#include <stdio.h>
int main()
{
	char a = -128;
	printf("%u\n", a);
	return 0;
}

答案:4,294,967,168
解析:
  a这里是有符号的char类型,二进制表示为
  a的原码 10000000 00000000 00000000 10000000
  a的补码 11111111 11111111 11111111 10000000
  截断 10000000
  %u是以无符号10进制输出
  整型提升 11111111 11111111 11111111 10000000
  十进制 2 ^ 32 - 2 ^ 7 = 4,294,967,168

代码3

#include <stdio.h>
int main()
{
	char a = 128;
	printf("%u\n", a);
	return 0;
}

答案:4,294,967,168
解析:
  a这里是有符号的char类型,二进制表示为
  a的原码 00000000 00000000 00000000 10000000
  截断 10000000
  %u是以无符号10进制输出
  整型提升 11111111 11111111 11111111 10000000
  十进制 2 ^ 32 - 2 ^ 7 = 4,294,967,168

代码4

#include <stdio.h>
int main()
{
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);

	return 0;
}

答案:-10
解析:
  i 这里是有符号的 int 类型,二进制表示为
  i 的原码10000000 00000000 00000000 00010100
  i 的补码11111111 11111111 11111111 11101100
  j 这里是无符号的 int 类型,二进制表示为
  j 的原码00000000 00000000 00000000 00001010
  i+j等于补码11111111 11111111 11111111 11110110
  原码 10000000 00000000 00000000 00001010

代码5

#include <stdio.h>
int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	
	return 0;
}

解析:
  这一串代码的运行结果是一个死循环,i是一个无符号的整型变量,当程序运行到0时,i–,输出的又是无符号的i,我们先看i=-1时的原码
  原码10000000 00000000 00000000 00000001
  补码11111111 11111111 11111111 11111111
  输出以无符号输出,就是把这个补码看成原码,因此是个正数大于0,循环继续。

猜你喜欢

转载自blog.csdn.net/weixin_43580319/article/details/111466619
今日推荐