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

题目

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),休眠一秒,隔一秒输出一个结果。如下图:
这里写图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值