整形提升和截断的再理解——例题详解

整形提升

关于表达式的隐式类型转换和整形提升,详见下面链接:

表达式隐式类型转换和整形提升

整形提升

对于整形提升,高位需要补位,那么补什么呢?
无符号数高位补0,有符号数高位补1;

例题详解:

例题1:

下面代码的输出结果是什么呢?

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

结果是什么呢?
在这里插入图片描述
结果是,a=-1,b=-1,c=255,这是为什么呢?
-1在内存中的存储补码为:11111111 11111111 11111111 11111111

-1转换为char a需要发生截断,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是有符号数补符号位,高位补1,
即:11111111 11111111 11111111 11111111 ——> -1

-1转换为signed char b需要发生截断,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是有符号数,补符号位,高位补1,
即:11111111 11111111 11111111 11111111 ——> -1

-1转换为unsigned char c需要发生截断 ,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是无符号数高位补0,
即:00000000 00000000 00000000 11111111 ——> 255

例题2:

下面代码的输出结果是什么呢?

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

	return 0;
}

结果是:128吗?
在这里插入图片描述
为什么结果会是这个呢?
-128在内存中的存储补码为:11111111 11111111 11111111 10000000
转换为char型,发生了截断,变为:10000000;
按照%u打印,先进行整形提升,是有符号数,补位符号位,
变成:11111111 11111111 11111111 10000000
最后按照无符号数打印,最高位不是符号位了,所以结果是232-127

注意:
整形提升的时候,看的是原本的类型。

例题3:

那么下面代码的输出结果是什么呢?

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

	return 0;
}

和例题2相比,这道题的结果是什么呢?
结果是128了吗?
在这里插入图片描述
为什么结果会是这个呢?
128在内存中的存储补码为:00000000 00000000 00000000 10000000
转换为有符号的char型,发生了截断,变为:10000000;
按照%u打印,先进行整形提升,是有符号数,补位符号位,
变成:11111111 11111111 11111111 10000000
最后按照无符号数打印,最高位不是符号位了,所以结果是232-127

例题4:

那么下面代码的输出结果是什么呢?

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

	return 0;
}

结果是多少呢?

在这里插入图片描述
i的原码:10000000 00000000 00000000 00010100
i的补码:11111111 11111111 11111111 11101100
j的补码:00000000 00000000 00000000 00001010
相加:11111111 11111111 11111111 11110110
按照%d有符号的打印,则:结果为-10
其实在无符号和有符号数相加的时候发生了隐式类型转换,往大了转

例题5:

那么下面代码的输出结果是什么呢?

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

是输出9——0吗?

结果是死循环:
在这里插入图片描述
为什么呢?
因为i是一个无符号的数,i - -,每次减少1,当i等于0 的时候,i=0,然后i - -的时候,是-1,-1整形提升为无符号的数,那么就是一个非常大的数字一直减减,所以会成为死循环。

例题6:

观察下面代码,结果是多少呢?


#include <stdio.h>

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d\n", strlen(a));
	return 0;
}

分析:
在- 1 - i 的时候发生提升,转换为整型计算,计算完赋值给char数组a的时候,发生截断,只取1个字节,即:后8位。
strlen求长度,遇到‘\0’,就会停止;而‘\0’,的ASCII码是0;所以当后8位为0,就能求出长度。
-1 - i,需要-256次才能保证后8位全为0,但是‘\0’,并不计算进strlen长度,所以结果是255。
结果:
在这里插入图片描述

例题7:

观察下面代码,判断结果是:

#include <stdio.h>
int main()
{
	unsigned char i = 0;
	for ( i = 0; i <= 255 ; i++)
	{
		printf("hello world\n");
	}

	return 0;
}

分析:
因为 i 是无符号的char型,char只看1个字节8位,所以i发生了截断和提升,当i从0一直++,会从0一直到255,而当再次++的时候,发生截断,256的后8位是0000 0000 所以i再次变为0,所以程序会死循环。
在这里插入图片描述
可是,如果将i<=255改成i<255,那么程序就不会变为死循环,而是打印255次就会结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无赖H4

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

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

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

打赏作者

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

抵扣说明:

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

余额充值