本文讲解有符号数和无符号数之间的转换。
针对同一数据类型有符号数和无符号数之间的转换,例如 int 和 unsigned int 之间和 char 和 unsigned char 之间 。这种情况下,二者之间的数据类型长度一致,不会发生转换后数据溢出而导致截断的问题。例如把一个int 类型转为unsigned char 类型,转换后数据存不下,导致被截断。
1. 首先针对这种情况,有符号类型和无符号类型中存储的数据是一致的,不一致的是数据的解释方式,有符号类型中最高位被解释为符号位,无符号数中最高位被解释为数据位,仅此而已。
例如 , char a = -1 ;
unsigned char b = a; (此处发生隐式类型转换)
我们看一下 a 、b 实际保存的数据。
a : 1111 1111(负数以补码表示) b : 1111 1111 二者一样,转换后,a、b中存储的数据是一样的。
我们看一下a、b 表示的意义。
a 是有符号数,最高位表示符号位,求a 的原码是1000 0001 ,表示-1.
b 是无符号数,最高位表示数据位,b 的原码是它本身 1111 1111,表示255.
2. 针对不同数据类型之间有符号数和无符号数之间的转换,如果是从一个长度短的类型转到长度长的类型,则不会两者在内存中存储的数据是一致的,不会发生截断。
例如: char a = -1;
unsigned int = a;
我们看一下 a 、b 实际保存的数据。
a : 1111 1111(负数以补码表示) b : 1111 1111 二者一样,转换后,a、b中存储的数据是一样的。
我们看一下a、b 表示的意义。
a 是有符号数,最高位表示符号位,求a 的原码是1000 0001 ,表示-1.
b 是无符号数,最高位表示数据位,b 的原码是它本身 1111 1111,表示255.
3. 如果 是从常长类型到短类型之间进行转换,则数据会被截断(高位丢失,低位保存)。
例如:short a = -256;
unsigned char b = a;
我们看一下 a 、b 实际保存的数据。
a : 1111 1111 0000 0000(负数以补码表示) b : 0000 0000数据被截断,转换后,a、b中存储的数据不一样的。
我们看一下a、b 表示的意义。
a 是有符号数,最高位表示符号位,求a 的原码是1000 0001 0000 0000 ,表示-256。
b 是无符号数,最高位表示数据位,b 的原码是它本身 0000 0000,表示0.
总结一下: 有符号和无符号数之间的转换,内存中存储的数据是不变的(存储不开则数据截断,保留低位),改变的仅仅是数据最高位的解释方式,是作为符号位还是作为数据位。