您的位置:首页 > 编程语言 > C语言/C++

《C语言深度解剖》signed,unsigned关键字后面3个问题的理解

2018-03-21 22:04 417 查看

题目

1.-0和+0在内存中是怎样存储的?

2.int i =-20 ;unsigned j =10;i+j 的值是多少?为什么?

3.下面的代码有什么问题?

unsigned i;
for(i=9;i>=0;i--)
{
printf("%u\n",i);
}


1.-0和+0在内存中是怎样存储的?

1.假设+0 和 -0 都是int数据。int型数据大小为4Byte = 32 bit
我们知道,整型数据在内存中存放的是二进制的补码。



2.int i =-20 ,unsigned j =10;i+j 的值是多少?为什么?

2.可能对这个问题很多人的第一反应结果为10。当然以整数形式输出:
printf("%d",i+j);
输出时unsigned 定义的变量值都是大于等于0的,所以结果为10。但对于,出现了unsigned关键字定义的变量,在我们不确定结果的时候最好进行简单的运算从而得出结果。上面提过,整形数据在内存中存放的是二进制的补码,整数的运算其实是二进制补码的运算。对于上面的表达式,我们以补码的形式进行运算(步骤如下):

i=-20 unsigned j=10



这样计算会相对比较麻烦,如果对于整数运算,以%d 的形式输出,我们可以通过整数运算得到结果,但如果是以无符号整数形式(%u)输出呢?结果还会是-10吗?我们可以使用补码进行计算,结果令人大吃一惊。至于前面的求补码然后相加运算都是一样的,但我们直到,无符号数是不可能小于0的。当我们计出补码时该怎么处理,上面我们求出了i+j 的补码。

11111111 11111111 11111111 11110110——补码,

计算机会把无符号数的最高位当成是这个二进制序列的一部分。所以以符号数形式输出时,输出的就是对应二进制数的大小。

即: 11111111 11111111 11111111 11110110的数值大小。

如果把这个二进制数当全是1 计算的话数值大小为 2^32-1 ,当我们当全1计算的话多加了9,所以其运算结果为2^32-1-9 = 4294967286

3.下面的代码有什么问题?

unsigned i;
for(i=9;i>=0;i--)
{
printf("%u\n",i);
}


定义了一个无符号的整形变量i,我们知道无符号数永远大于等于0,所以i>=0 的判断一直为真。程序执行会死循环。

具体的情况我们依然可以通过补码进行,。我们知道-1的补码为32个1,i为无符号整形,所以其对应10进制数位:2^32 -1 =4294967295。所以程序的运行结果为:9,8, 7, 6,5,4, 3,2, 1,0,4294967295,4294967294 …

我们可以使用visual studio 对结果进行测试。

源代码:

#include<stdio.h>
#include<Windows.h>

int main()
{
unsigned i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
Sleep(1000);
}
return 0;
}


为了清楚的观察结果,代码里使用Sleep(1000),休眠一秒,隔一秒输出一个结果。如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息