哈喽啊,铁汁们,许久未见,澳^甚是想念你们(滑稽)
近日一好友突然问我,你学了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天



