C语言的有符号数的符号位扩展(有符号数前面进行符号扩展)

小编:霸主 更新时间:2022-08-25

char和int类型都是有符号数类型,char类型的变量占据1个字节的容量,int类型的变量占据4个字节的容量。那么,把char类型变量赋给int类型变量,会有什么问题产生?

我们会很直观地认为,把1个字节大小的数据,放入4个字节大小的容量,没有任何问题啊!我们做如下的一个测试例子:

C语言的有符号数的符号位扩展(有符号数前面进行符号扩展)

程序运行结果如下:

C语言的有符号数的符号位扩展(有符号数前面进行符号扩展)

可以看到b的结果也是-1,这是因为,把char类型变量赋值给放入int类型变量时,是把char类型变量的数据放入int类型变量的第字节,剩下的高位字节使用char类型变量的符号位扩展填充。所以,a变量的二进制是 1111 1111,其中符号位是1,那么,放入int类型变量的时候,把a变量的 1111 1111 数据放入int类型变量的低字节,高字节使用符号位1扩展填充,最终是1111 1111 1111 1111 1111 1111 1111 1111二进制数值,表示为-1这个数值。

下面来讲解一个应用实例,在网络通信或者串口通信的过程中,传输的数据是一个一个字节的数据流。例如,一个字节的数据是128(十六进制是0x80),对应是二进制是1000 0000,那么,就应该把这个数据当作“无符号”数看待,这样,一个字节中的8位数据才完全做为数值位,才表示128这个数值。

如果把128这个数值作为“有符号”数看待,那么,最高位作为符号位,剩下的7位作为数值位,那么,128这个数值当作有符号数看待时,其数值就发生了改变。测试例子如下:

C语言的有符号数的符号位扩展(有符号数前面进行符号扩展)

程序运行结果如下:

C语言的有符号数的符号位扩展(有符号数前面进行符号扩展)

可以看到,char类型是“有符号数”类型,那么,存储在char类型变量x中的数据当作“有符号数”看待。所以,128数值存储在1个字节中的二进制是1000 0000,当以十六进制输出%x的时候,默认输出4个字节的宽度,所以,1000 0000中的符号位向高位扩展,扩展到4个字节的空间。所以,得到4个字节中的二进制数据是:1111 1111 1111 1111 1111 1111 1000 000,表示是十六进制就是0xffffff80;

在第二行输出中,对变量x的输出,强制转换为无符号类型,那么,就把变量x当作无符号数看待,就输出其数值0x80。