1.了解无符号数与符号数比较大小时的转换关系:
1.1 从一个题目延申开展了解
#include <stdio.h>
int i;//i是全局变量,不初始化,默认是0
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
这里我们来判断应输出的是什么?
当时我的思路就是,开始定义整形i变量初始化为0,执行下一条语句后,i为-1,sizeof(i)计算整形变量的大小,i为整形变量占4个字节,答案就很明显了 i == -1,sizeof(i)== 4 所以应输出'<'。
但是答案是'>'!!现在我们以下认真一波
1.2我们需要先知道的是sizeof的返回类型;
在 C 语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符。他的返回值是这个数据在内存中所占领的字节个数;而这个返回值(字节个数)是一个无类型数据也就是无符号整数。
所以这里我们就要思考的是当无符号整数与有符号整数应该如何判断呢?
2.有符号类型与无符号类型是如何转换的?
概念:简单来说我们以一个字节的char类型举例了解,有符号类型在8个比特位中,第一个位表示符号(0为正数,1为负数)其他为表示数据的大小,而无符号类型中8个比特位都用来表示数据的大小。
int main()
{
int b = -1;
unsigned int a = 1;
if (b > a)
{
printf(">");
}
else
{
printf("<");
}
return 0;
}
这里我们以这段代码分析 (答案是'>')
2.1 数据在内存中存储形式
在计算机中是以补码的形式存储的,这里我们来研究整形的存储形式。我们知道整形类型占四个四节,每个字节占8个比特位。这里以有符号整形类型-1和无符号整形类型1为例:
-1
10000000 00000000 00000000 00000001 //原码
11111111 11111111 11111111 11111110 //反码(符号位不变,其他位取反)
11111111 11111111 11111111 11111111 //补码(反码+1)
这里说明一下,正数的原码,反码,补码相同;
所以这里无符号整形 a 的存储形式为他本身
1
00000000 00000000 00000000 00000001
2.2 对于有符号类型与无符号类型比较时转换进行讨论
当我们上面针对每个类型在存储中的存储形式进行研究后,我们就来研究下究竟是无符号类型转换为有符号类型,还是有转换为无类型呢?
下面我们进行假设是无符号类型转换为有符号类型:
-1
11111111 11111111 11111111 11111111
1
00000000 00000000 00000000 00000001
无符号类型1转换为有符号类型,最高位为0,则为正数为+1。
有符号类型-1,最高位为-1,则为负数为 (我就不算了~~~)
结果很明显,正数肯定是大于负数的,则代码应该结果为 b<a,但是我们刚才在编译器算的结果为b>a,所以假设是错误的。
下面我们进行假设是有符号类型转换为无符号类型:
-1
11111111 11111111 111111111 11111111
1
00000000 00000000 00000000 00000000
有符号类型-1转换为无符号类型,最高位变为用来计算数据的大小,则为非常大的一个数据;
无符号类型不变,依旧为 1。
当我们进行比较后,发现结果成立,通过以上的实验分析我们可以得到结论;
.当表达式中存在有符号数和无符号数类型时,所有的操作都自动转换为无符号类型。可见无符号数的运算优先级高于有符号数。
其实进行这些实验过程中,还有很多的需要我们去探索的,比如:为什么计算机存储的过程要以补码的形式存储,当是不同类型进行比较的时候需要运用整形提升的概念来求解,这篇文章只是建立在有符号整形类型与无符号整形类型进行的比较。