栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

震惊!关于整型提升不得不说的那些事。

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

震惊!关于整型提升不得不说的那些事。

哈喽啊,铁汁们,许久未见,澳^甚是想念你们(滑稽)

         近日一好友突然问我,你学了20来天了,代码水平高不高。

好家伙,我听到这问题当时啪的一声就站起来了,反手在他电脑上敲了代码:

	while(printf("我的代码水平高吗?")) 
	{
		scanf("%s",answer);
		if(strcmp(answer,"高")==0)
		break;
		else
		printf("回答不正确,请重新输入"); 
		
	}

好友:你糊弄我呢?

我:你就说高不高吧。

咳咳,咱们言归正传:

        近日楼主在做某道算法题时发现用字符数组以%s格式接收整型数字时,用数组的每个元素减去0的ASCII码值可得到原来的数字的每一位。针对超超超大数字仅做数位上的运算时有奇效。

        再一联想到以字符接收整型数字,应当会产生“奇奇怪怪”的效果。

目录

话不多说,直接给铁汁们上题:

整型提升:

整型提升规则分为两种:

总结整型提升:

整型提升的意义:

给铁汁们上菜!!!

思考:


话不多说,直接给铁汁们上题:

        

	char a=-1;
	signed char b=-1;
	unsigned char c=-1;
	printf("%d ",a);
	printf("%d ",b);
	printf("%d ",c);

铁汁们,答案是-1 -1 -1

                   

                

的话,怎么可能嘛。

嘿嘿,其实是-1 -1 255

怎么来的呢,也不卖关子了,以%d形式打印字符时,涉及到整型提升。

整型提升:

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

有的铁汁看到这啪的一下就站起来了,说:这什么玩意。

 莫慌,铁汁们,让我给大家仔细(好好)讲讲(吹牛皮)。

首先,咱们看看原来的代码的:

 当我们定义一个char/signed char/unsigned char变量存储-1时,他应当只能存储-1的32比特位的8位。那么问题来了嗷,铁汁们,char到底是存储右边低位的8个比特位,还是存储左边高位的8个比特位呢。

(有的铁汁当时就站起来了,说左边右边不一样都是8个1吗。  可万一这里存储的不是-1,左边和右边到底存储哪一个就显得有必要了解了。这里应当涉及到:大端/小端存储模式)

感兴趣的铁汁们可以在下面阅读到关于大端/小端存储模式的区别。这里明确告诉大家这里存储右边的8位。(强转滑稽)(目前楼主还没写,写了再补上)

所以a b c都应当存储了11111111  共8个比特位。

我们知道:int型整型数据是32位比特位。对应打印格式为%d

                  那么非整型比如char 以%d格式打印时会发生什么情况呢?

答案是:整型提升

在这说明:整型提升,将计算时,某些不是整型的数据类型(比如char,short int等)转化为32位的整型进行计算。

前面有:

 铁汁们观察一下:咱们细心观察下这段代码。char 与signed char数据类型一样,都是有符号位的数据类型,而unsigned char为无符号的数据类型。所以这里有区别的是有符号的char/signed char与无符号的unsigned char。既然在整型提升里上面提到了有符号和无符号。那么其实整型提升就是与数据类型是否有符号或无符号相关。

整型提升规则分为两种:

一种对于有符号的数据类型,一种对于无符号的数据类型。那么具体 应当怎么实施,下面给出方法:

对有符号数据类型:以最高位(符号位)补齐32位来进行整形计算。

对无符号数据类型:前面直接补0,以补齐32位来进行整型计算。

比如:

对有符号的char数据类型整型提升:

得到32位的补码:11111111 11111111 11111111 11111111 

发现整型提升后与原来-1的补码相同,所以其对应的原码为-1

signed char存储补码的也是:11111111 

与char同为有符号的数据类型。所以两个结果一样都为-1

对无符号的unsigned char数据类型整型提升:

       

 得到32位的补码:00000000 00000000 00000000 11111111

由于其最高位0,为正数,正数原码反码补码相同,所以其原码也为:

                               00000000 00000000 00000000 11111111

对应的数字为255,所以c打印的为255。

总结整型提升:

整型提升根据本身的数据类型可存储的大小,从数字补码(在这为-1的补码)的右边截取对应的存储长度(在这char/signed char/unsigned char为一个字节8个比特位)。然后根据数据类型有无符号,有符号的以最高位在左边补齐32位,无符号的左边直接补0,补齐32位得到补码。最后以补码对应的原码得到的数字计算。

整型提升的意义:

虽然机器指令中可能有现两个8比特字节这种字节相加指令,但是一般用途的CPU是难以直接实现这样的字节相加运算的。

所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。

CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。而表达式的整型运算要在CPU的相应运算器件内执行。

因此,两个char类型的数进行相加运算时,是在CPU中执行,自然而然的需要先转换为CPU内整型操作数的标准长度。
 

有铁汁满不在乎的表示:就这啊。我还以为多狠呢。

 不得不说,咱们铁汁就是聪明,就是那个嗷,给力嗷。

给铁汁们上菜!!!
	char c=-1;
	printf("%d ",sizeof(c));	
	printf("%d ",sizeof(+c));	
	printf("%d ",sizeof(++c));	
	printf("%d ",sizeof(!c));

铁汁们,答案是:

1 4 1 1

铁汁们嗷,这里+c怎么大小为4字节啊。

这是楼主查到的回答:

 哦~原来前缀+还能够改变大小啊(滑稽)

咳咳,楼主查到的回复仅仅有个前缀+的解释。

但是楼主自己尝试了下,给出下面的代码:

思考:
	char c=-1;
	printf("%d ",sizeof(1*c));	
	printf("%d ",sizeof(-c));	
	printf("%d ",sizeof(~c));	

结果为:4 4 4

为啥呢铁汁们,留给咱们下去思考吧。嘿嘿

————————————————分割线———————————————————————

                                                                                                                      记编程的第29天

                                                                                                                            来CSDN的第14天

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/296620.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号