C语言中的截断与整型提升

C语言中的截断与整型提升

我们首先来看一段代码:

#include<stdio.h>
#include<stdlib.h>
union Un//--联合体
{   
	char c;
	int i;
};
int main()
{
   //联合变量的定义
	union Un un = { 0 };
   //计算联合变量的大小
	printf("%d\n", sizeof(un));//--结果为4,联合体按照最大的变量开辟空间
   // 下面输出的结果是一样的吗?
	un.c = 129;//        10000001
   printf("%d\n", un.c);//-127
   printf("%d\n", un.i);//129
   system("pause\n");
   return 0;
}

猜猜结果吧!
在这里插入图片描述来看看真实的结果:
在这里插入图片描述
这是为什么呢?这就涉及到了C语言中的截断和整型提升。

截断:

在c语言中进行变量赋值的时候,如果将字节多的数据类型赋给一个字节少的数据类型,会发生“截断”。 发生这种情况的原因是:在赋值过程中只将占字节较长的变量的低位赋给占字节较短的变量。

整型提升:

整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。

我们都知道,int类型是32位(4字节),char类型是8位(1字节)。
129在int类型中的存储格式如下:
在这里插入图片描述
129在char类型中,由于char的存储空间不足4字节,所以只会存原int类型的低8位,存储格式如下:
在这里插入图片描述
此时,发生截断。 原来的int类型的un.i的值发生截断。
这时候你或许又有疑问了,那结果不应该是:129和129吗?
这又牵扯到了打印的时候整型提升的问题。
首先来熟悉一下整型提升的规则吧:

  1. 若是有符号数,则前面8*3位补符号位。
  2. 若是无符号数,则前面8*3位补0。

现在再来看,原来的char类型的un.c被提升成了int类型,因为这里是有符号char类型(%d格式打印),所以10000001中的第一位被解释为符号位,整型提升为:
在这里插入图片描述
到这里你或许又会说,第一个结果应该是上面的二进制换成整数吧。
别急,别急!这又牵扯到了数字在计算机中的存储问题。
计算机存储的是补码,负数的补码是反码+1,正数的补码是它本身。
那我们来求一下上面这个结果的原码吧:
在这里插入图片描述
因此:

printf("%d\n", un.c);

的结果为:-127.
我们再了解一下负数在计算机中存储的形式吧:
在这里插入图片描述
第二个结果:

printf("%d\n", un.i);

为129。
你或许又迷糊了,刚才赋值的时候,原来的int类型的un.i的值不是发生截断了吗?那它以“%d”形式打印的时候不应该也要整型提升吗?结果和第一个一样啊。
是这样的,un.c占1个字节(8位)所以它最高位的1同时也是符号位,要打印时要把它提升成“%d”要求的有符号的占4个字节的数据。(截断以后进行整数提升)。整数提升以后,又因为它是负数,在计算机中存储的是负数的补码,打印出来的是原码,因此要进行求原码的操作。(如果是负数要先求它存储在计算机里面的补码进行截断再进行上述操作 )
un.c在赋值时发生截断,可是它剩余的三个高位都是0.(24个0),在计算机里是存在的,只是赋值的时候截断了,截取了最低一个字节的8个位。打印的时候其他位补0就可以啦。(如果是负数,要先求补码,再进行截断)(拿un.c=511试,可以知道打印的时候其他位补0,不是补符号位)
你明白了吗?那,小试牛刀如何?

#include<stdio.h>
#include<stdlib.h>
union Un//--联合体
{   
	char c;
	int i;
};
int main()
{
   //联合变量的定义
	union Un un = { 0 };
   //计算联合变量的大小
	printf("%d\n", sizeof(un));//--结果为4,联合体按照最大的变量开辟空间
   // 下面输出的结果是什么?
	un.c = -129;
   printf("%d\n", un.c);//?
   printf("%d\n", un.i);//?
   system("pause\n");
   return 0;
}

结果:
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
union Un//--联合体
{   
	char c;
	int i;
};
int main()
{
   //联合变量的定义
	union Un un = { 0 };
   //计算联合变量的大小
	printf("%d\n", sizeof(un));//--结果为4,联合体按照最大的变量开辟空间
   // 下面输出的结果是什么?
	un.c = 257;
   printf("%d\n", un.c);//?
   printf("%d\n", un.i);//?
   system("pause\n");
   return 0;
}

结果:
在这里插入图片描述
你都做对了吗?没做对的再去复习一下吧。如果你全都做对了,哇哦,perfect,说明这部分内容你已经掌握地很好了呢。

发布了34 篇原创文章 · 获赞 2 · 访问量 941

猜你喜欢

转载自blog.csdn.net/weixin_44091229/article/details/104628257
今日推荐