整型提升 + 测试题。

下面这段代码的输出结果是什么?

#include <stdio.h>

int main()
{
    char a = -1;
    signed char b = -1;
    unsigned char c = -1;
    printf("a=%d, b=%d, c=%d", a, b, c); 
    return 0;
}

我先把运行结果放下来(我的是VS2019环境)

 

 结果 a = -1 、 b = -1 、 c  = 255,那为什么呢?

这里就涉及整型提升、数据在内存中的存储,原码、反码、补码的知识,我前面的文章有提到数据的存储、已经原码、反码、补码的知识,这里不在详细解释。

下面是原码、反码、补码的转换方法:

回归开始的题,先从 a 开始吧, a = -1 是负数,所以原码、反码、补码如下:


10000000000000000000000000000001 -1原码

11111111111111111111111111111110 -1反码

11111111111111111111111111111111 -1补码

因为 a 是 char 类型只能存放 8 个 bit 位,所以发生数据截断,取低位的 8 个 bit 位。

11111111 ——— 截取后的 a (补码)

但是 a 以 %d 整型(32 个 bit 位)打印,要发生整型提升(提升后还是补码)

又因为 a 是 char 类型, 我的 VS环境下,把 char 当做 signed 对待,所以 a 最高位是符号位,整型提升的话,要补符号位,如下:

11111111111111111111111111111111  —— 提升后的 a (补码)

提升后的二进制数依然是补码,因为数据在内存中存的就是补码,打印出来的话要转为原码:

11111111111111111111111111111111 —— 补码并且是有符号的

10000000000000000000000000000000 —— 反码(符号位不变,其它位按位取反)

10000000000000000000000000000001 —— 原码(反码+1)

所以 a = -1

因为 b 是 signed(有符号),那么与 a 的方法相同,所以 b = -1。

下来就是 c ,那么 c 跟前面 a、b 一样先写出原码、反码、补码,如下:

10000000000000000000000000000001 —— -1原码

11111111111111111111111111111110 —— -1反码

11111111111111111111111111111111 —— -1补码

因为 c 是 char 类型只能存放8个bit位,又要截断也是取低位:

11111111 —— 截取后的 c

这里 c 也是以 %d 整型(32个bit位)打印,打印的话也要发生整型提升(提升后还是补码)

但是这里 c 是 unsigned (无符号的char)整型提升的话与前面不同,无符号提升的话,高位补 0,不补符号位!

00000000000000000000000011111111 —— 提升后的 c 

因为 c 最高位是 0,所以是正数,正数的原码、反码、补码相同!

所以 c = 255

发生整型提升是根据要被提升的数的类型提升的。

比如 a 是char,是根据 signed 提升的,我的 VS 环境下根据 signed 提升的。

b 是 signed, 所以 b 直接根据有符号规则提升。

但是 C 语言中我们通常用的类型 char ,它究竟是被当做 signed 型还是 unsigned 型,由编译器决定的。

而 c 是 unsigned 类型,直接根据无符号规则提升。

有符号提升:根据最高位也就是符号位提升,补的是符号位。

无符号提升:高位全补 0。

第二题:

#include <stdio.h>

int main()
{
    char a1 = -128;
    printf("%u\n", a1);

    char a2 = 128;
    printf("%u\n", a2);
    
    return 0;
}

第三题:

#include <stdio.h>

int main()
{
    char a[1000];
    int i;
    for(i = 0; i < 1000; i++)
    {
        a[i] = -1-i;
    }
    printf("%d\n", strlen(a));

    return 0;
}

第四题:

#include <stdio.h>

unsigned char i = 0;

int main()
{
    for( i = 0; i <=255; i++)
    {
        printf("Hello word\n");
    }
    return 0;
}

这些题的做法与第一题做法相似,牵扯整型提升、数据在内存中的存储(原码、反码、补码)的知识,可以试着挑战一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值