实验目的:
理解C语言中如何计算补码,掌握“矛盾”赋值时如何处理数据。
实验步骤:
1.验证没有赋值的变量的值是“随机的”。
1.1在VC6.0没有赋值的整型变量其存储单元中每个字节都是0xcc。如程序
#include
void main()
{
long i;
short j;
printf("%lx,%hx\n", i, j);
}
的输出为:cccccccc,cccc。
但是这只是vc6.0为了方便观测数据主动为程序中的变量设置的状态。
1.2在Win-TC可以清楚地看出,没有赋值的变量的值是“随机的”。
2.计算机中处理整型字面量的方式。
2.1计算机中存储整数的补码形式,因此遇到整型字面量时会首先将其转换为补码形式,但是需注意其转换方法。
遇到正数,正数的补码形式与原码的相同,直接将其转换成二进制形式即可。如65535将被转换成1111 1111 1111 1111或(认为其类型是长整型)被转换成0000 0000 0000 0000 1111 1111 1111 1111(0xffff);0x80000001将被转换成1000 0000 0000 0000 0000 0000 0000 0001(0x80000001)。
遇到负数,先忽略负号将其转换成二进制形式,再取反,最后加1即得到了补码形式。如-65535先忽略负号将其转换成二进制形式:0000 0000 0000 0000 1111 1111 1111 1111,再取反:1111 1111 1111 1111 0000 0000 0000 0000,最后加1即得到:1111 1111 1111 1111 0000 0000 0000 0001(0xffff0001);对于-0x80000001,理论上其是无法用4个字节的补码形式表示的,但C语言不考虑溢出的问题同样是先忽略负号将其转换成二进制形式:1000 0000 0000 0000 0000 0000 0000 0001,再取反:0111 1111 1111 1111 1111 1111 1111 1110,最后加1即得到:0111 1111 1111 1111 1111 1111 1111 1111(0x7fffffff)。
2.2验证程序如下。
#include
void main()
{
long i, j;
i = 65535;
j = 0x80000001;
printf("%lx,%lx\n", i, j);
i = -65535;
j = -0x80000001;
printf("%lx,%lx\n", i, j);
}
程序的输出为:
ffff,80000001
ffff0001,7fffffff
3.在程序中出现整型赋值“矛盾”的情况时,C语言采用简单的处理方式:先将整型字面量转换成补码形式,再根据存储单元实际的大小从低位到高位选择相应的字节数存入。
如有:short i;当有i=0x80000001;,变量i存储单元中实际的状态为0x0001;当有i=-0x80000001;,变量i存储单元中实际的状态为0xffff。验证程序如下。
#include
void main()
{
short i, j;
i = 0x80000001;
j = -0x80000001;
printf("%hx,%hx\n", i, j);
scanf("%lx%lx", &i, &j);
printf("%hx,%hx\n", i, j);
}
程序的运行情况如下:
1,ffff
0x80000001 -0x80000001
1,ffff
4.在VC6.0中有语句long i, j = -1;,则变量i的存储状态为0xcccccccc,而变量j的存储状态为0xffffffff。当有scanf(“%hx%hx”, &i,&j);且用户输入0x80000001时,scanf函数只会把用户输入数据中的低2个字节的数据存入变量i和j的低2个字节,因此变量i的存储状态变为0xcccc0001,变量j的存储状态变为0xffff0001。变量i的实际值为1×-231+1×230+1×227+1×226+1×223+1×222+1×219+1×218+1=-859045887。变量j的实际值为(前面的1可以省略故j与0x10001相等)1×-216+1=-65535。验证程序如下。
#include
void main()
{
long i, j = -1;
printf("%lx,%lx\n", i, j);
scanf("%hx%hx", &i, &j);
printf("%lx,%lx\n", i, j);
printf("%ld,%ld\n", i, j);
}
程序的运行情况如下:
cccccccc,ffffffff
0x80000001 0x80000001
cccc0001,ffff0001-859045887,-65535