整型提升与截断

这篇更倾向通过例题梳理知识点,所以干货集中在几道例题讲解中;

目录

一、什么是整型提升

二、什么是截断

三、什么时候发生整型提升

四、什么时候发生截断

五、整型提升的规则

六、整型提升的例题


一、什么是整型提升

没错,又是该屎的·概念君 :

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

二、什么是截断

截断,顾名思义(木头太长了,我要把你砍断一些,才能装进一个盒子里);

具体就是:是将占用字节数较多的变量赋值给占用字节数较少的变量时,如将long(16个字节)赋值给int(4个字节)时,这时候long类型的比特位,只将最低的8位赋给了char类型的变量,而高位比特位全部被“截断”;

三、什么时候发生整型提升

低数据类型向高数据类型转化unsigned优先【如图】,或者进行运算时不满足int;

四、什么时候发生截断

高数据类型向低数据类型转化时;

五、整型提升的规则

【无符号整形提升补0】【有符号位整型提升补符号位】

这个很重要

int main() {
	char k = -128;
	printf("%u\n", k);//以无符号整型输出,不代表char k的数据类型是无符号;不影响char k的整型提升

int main() {
	char k = -128;
	printf("%u\n", k);//以无符号整型输出,不代表char k的数据类型是无符号;不影响char k的整型提升

	return 0;
}

//10000000000000000000000010000000
//11111111111111111111111101111111
//11111111111111111111111110000000【截断】
//100000000【存的】
//11111111111111111111111110000000【整型提升】【这里的%u是以无符号格式输出,不是说char k是无符号类型】
//11111111111111111111111110000000【以无符号整型打印这串二进制,则认为这串二进制没有符号位,故 原=反=补】4294967168

//输出时%u把最高位特性变了,%u认为他没有符号位,不进行原反补的转化;
//如果%d则先把11111111111111111111111110000000转化位原码在打印;-128
sizeof(k);int k=-1

六、整型提升的例题

例1.

截断与提升的过程:

首先,我们先来看一个代码

#include<dtdio.h>

int main() {
	
	int k = -1;
	char a = k;
	printf("%d\n", k);//打印-1

    return 0;
}
演绎内存

我们都能知道打印-1;但为什么?过程是怎么样?

这个就是这题的重点 

这个代码重点是,k的值是怎么存进a的;

首先-1的二进制原码1000 0000 0000 0000 0000 0000 0000 0001

以补码存储:1111 1111 1111 1111 1111 1111 1111 1111

当执行到char a=k;时,char 是一个字节,有8个比特位;

然而32个比特位的int k=-1的补码1111 1111 1111 1111 1111 1111 1111 1111显然存不下;

于是,本章的重点截断来了

 int k=-1的补码1111 1111 1111 1111 1111 1111 1111 1111

根据目录的 什么是截断:  “只将最低的8位赋给了char类型的变量,而高位比特位全部被“截断”;

将1111 1111存入了char a里;

这时,以%d输出【%d输出整型】,char 会进行整型提升

于是,本章的重点整型提升来了

根据目录的 整型提升的规则:【无符号整形提升补0】【有符号位整型提升补符号位】

1111 1111 --->1111 1111 1111 1111 1111 1111 1111 1111

提升完,然后输出的时候转化为原码

1000 0000 0000 0000 0000 0000 0000 0001

于是输出-1;

不理解原码反码补码可看http://t.csdn.cn/0aYSg

例2.

符号位的影响

#include<stdio.h>

int main(){

int a=-1;
printf("%u",a);//打印4294967295

return 0;
}

int a=-1的补码

1111 1111 1111 1111 1111 1111 1111 1111

%u是以无符号整型输出;首位1不再是符号位;

原反补相同;输出1111 1111 1111 1111 1111 1111 1111 1111的值

例3.

无符号位整型提升补0;

#include<stdio.h>

int main() {
	
	unsigned char c = -1;//%d输出整型提升
	
    printf("%d\n", c);

	return 0;
}
	

unsigned char c=-1的补码:

1111 1111【这里的1不代表符号位

%d输出,需要整型提升:无符号位整型提升补0--->0000 0000 0000 0000 0000 0000 1111 1111

经过整型提升后的0000 0000 0000 0000 0000 0000 1111 1111

显然符号位是0;原=反=补

于是输出0000 0000 0000 0000 0000 0000 1111 1111

=255

例4

int main() {
	unsigned char a = 200;
	unsigned char b = 100;
	unsigned char c = 0;
	c = a + b;
	printf("%d %d", a + b, c);//300,44

	return 0;
}

首先c等于多少呢?

a+b=【00000000000000000000000100101100=300】怎么来的?

我们知道,在电脑中,char类型值的运算,不满整型,于是他进行整型提升后再以补码参与运算

00000000000000000000000011001000

+

00000000000000000000000001100100

=

00000000000000000000000100101100=300

但显然不这么容易

a+b的值还要存入c,c是一个char类型,只有1个字节,显然存不下;发生截断

于是存储后八位

char c=00101100=44

那么a+b以%d打印呢?等于多少呢?

显然%d是整型方式输出,于是直接输出的300

例5

#include<stdio.h>

int main() {

	int a = -1;
	if (sizeof(a)>a) {
		printf("李四\n");
	}
	else {
		printf("张三\n");
	}

}

这道题会打印什么呢?

答案是【张三】

为什么呢?我们来看一下这个代码

将a用具体的常量值-1代替】:

 似乎......这里电脑试图将-1转化为无符号数

内错,我们可能忽略了一个特点:sizeof的数据类型是无符号整型,且它是一个运算符

两个数参与运算,类型不同需要转化为同类型,根据低数据类型向高数据类型转化unsigned优先

 显然char a=-1在这里的a显然会提升为无符号整型

char a=10000001的补码11111111整型提升补符号位

11111111111111111111111111111111

于是sizeof(a)>a=4294967295显然不成立

打印张三

 以上就是整型提升的基本内容;

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡涂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值