目录
注意:提升后得到的是补码。要根据打印类型,判断是否有符号位;有效数字
一.相关知识点
1.截断:
直接保留低位的二进制位
2.整形提升:
表达式中的字符(char)和短整形(short)操作数在使用之前被转换为普通整型(int),这种转换称为整型提升。
3.如何 截断,整型提升?
整型提升是按照变量的数据类型的符号位来提升的
(1)负数
char c1 = -1;
截断:-1的补码为:11111111111111111111111111111111 。 -1为int占4字节,c1是char占1字节。
直接保留 int 所占4字节中低位的1字节的二进制位:11111111
整型提升:因为 char 为 signed char 。所以整形提升的时候,高位补充符号位,即为1
提升后的结果为:11111111111111111111111111111111
(2)正数
char c2 = 1;
截断:1的补码为:00000000000000000000000000000001 。1为int占4字节,c1是char占1字节。
直接保留 int 所占4字节中低位的1字节的二进制位:00000001
整型提升:因为 char 为 signed char 。所以整形提升的时候,高位补充符号位,即为0
提升后的结果为:00000000000000000000000000000001
(3)无符号整型,高位补0
注意:提升后得到的是补码。要根据打印类型,判断是否有符号位;有效数字
二.例题
1.
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d,b=%d,c=%d", a, b, c);
return 0;
}
题解:
int main()
{
char a = -1;
//-1 是整数,32bit
//11111111111111111111111111111111 (int)-1的补码
//11111111 - char a 截断
//11111111111111111111111111111111 提升(得到补码)
signed char b = -1; //和a等价
unsigned char c = -1;
//11111111111111111111111111111111 (int)-1的补码
//11111111 - char a 截断
//00000000000000000000000011111111 - 提升,无符号的整型,高位补0
//
// -1 -1 255
printf("a=%d,b=%d,c=%d", a, b, c);
//%d是打印有符号的整数
return 0;
}
2.
int main()
{
char a = -128;
printf("%u\n", a);
//%u 打印无符号整型
return 0;
}
题解:
int main()
{
char a = -128;
//10000000000000000000000010000000
//11111111111111111111111101111111
//11111111111111111111111110000000 - 128的补码
//10000000 - a
//11111111111111111111111110000000
//%u - 第一位不是符号位
printf("%u\n", a);//4294967168
return 0;
}
3.
int main()
{
char a = 128;
printf("%u\n", a);
return 0;
}
题解:
int main()
{
char a = 128;
//00000000000000000000000010000000 - 128的补码
//10000000 - a
//11111111111111111111111110000000
printf("%u\n", a);//4294967168
return 0;
}
4.
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}
题解:
int main()
{
int i = -20;
unsigned int j = 10;
//10000000000000000000000000010100 - -20的原码
//11111111111111111111111111101011 - -20的反码
//11111111111111111111111111101100 - -20的补码
//00000000000000000000000000001010 - 10的补码
//11111111111111111111111111110110 - 和的补码
//11111111111111111111111111110101 - 和的反码
//10000000000000000000000000001010 - 和的原码
printf("%d\n", i + j);//-10
return 0;
}
疑问:不应该算数转换为unsigned int 吗?
如果这样,根据和的反码,第一位不是符号位,结果为4294967286
但是,我们是以 %d 形式打印的,如果是以 %u 打印,确实是4294967286。
我以 %d(有符号的整数) 的形式打印,我就认为内存里存的是有符号数。
%u 我就认为内存里存的是无符号数。
理论上说,i+j 结果确实是无符号数。但是你是个无符号数也悠不住我用 %d 来打印。
一个数据放在内存里,它有无符号没法确定,是用的人决定它有无符号
从哲学角度来说,一个东西是什么,取决于看待的人的视角
5.
(1)
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
}
return 0;
}
由于 i 是 unsigned int ,所以 i 不论怎么减,都不会 > 0 。
我们这样演示:
#include <windows.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000);
}
return 0;
}
(2)
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}
strlen 统计 ' \0 ' 之前的个数,' \0 ' 的ASCII码值为0 。所以本题是想让你判断,什么时候 a 里放第一个0
char 大多数是 signed char 其取值范围为 -128~127
所以放到 a 里的数字依次是:-1 -2 -3 ...... -127 -128 127 126 ...... 2 1 0 -1 -2 ......
到 0 之前是 128+127=255,结果就是255
(3)
unsigned char i = 0;//0~255
int main()
{
for (i = 0; i <= 255; i++)
{
printf("hello world\n");
}
return 0;
}
i <= 255 的判断进入循环条件一直成立,循环不会停下来,一直打印 hello world
6.
int main()
{
char a = 3;
char b = 127;
char c = a + b;
printf("%d", c);
return 0;
}
题解:
int main()
{
//char --> signed char
char a = 3;
//00000000000000000000000000000011
//截断
//00000011 - a
char b = 127;
//00000000000000000000000001111111
//截断
//01111111 - b
char c = a + b;
//00000011
//01111111
//整型提升
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010 - 和的补码
// 截断
//10000010 - c
printf("%d\n", c);//-126
//%d 是打印十进制的整数
//11111111111111111111111110000010 - 补码
//11111111111111111111111110000001
//10000000000000000000000001111110 - 原码
//-126
return 0;
}
本篇的分享就到这里了,感谢观看,如果对你有帮助,别忘了点赞+收藏+关注。
小编会以自己学习过程中遇到的问题为素材,持续为您推送文章