面试系列11--有符号与无符号的类型转换以及数位扩展问题

题目:

  int main()
  {
      unsigned int un;
      unsigned char uch;
      uch = (unsigned char) 128;
      un = uch;

      printf("un = %d/n", un);
      printf("un = %u/n", un);

      system("PAUSE");
      return 0;
  }

  int main()
  {
      int     n;
      char    ch;
      ch = (char) 128;
      n = ch;

      printf("n = %d/n", n);
      printf("n = %u/n", n);
  }

  请问以上两道题的输出是什么

解答:

首先我们需要了解相关知识。

补码表示法 (计算机中,整数通常是以补码来表示的)
正数: 最高有效位为0表示符号为正,数的其余部分则表示数的绝对值
负数: 用一个简单的方法来表示负数负数相对应的正数,用补码表示,按位取反,最后在末位(最低位)加1

用补码表示数时的符号扩展问题。比如从8位扩展到16位,从16位扩展到32位
正数的符号扩展应该在前面补0,而负数的符号扩展则应该在前面补1

(微软竟然给了一个 SafeInt 类的实现来帮助程序员避免对应的错误)


在上面的代码中,第一段代码:

uch = (unsigned char) 128;    ->    uch = 0x80 = 1000 0000

un = uch;    ->    (int)n = 0x00000080 = -128 由于 uch 是无符号型,所以高位补1

因此第一段代码的输出应该是:

un = 128
un = 128

第二段代码:

ch = (char) 128;     ->     ch = 0x80 = 1000 0000
n = ch;      ->     (int)n = 0xffffff80 = -128  由于 ch 是有符号型,所以高位补0

因此第二段代码的输出应该是:

n = -128
n = 4294967168

题目:

  int main()
  {
      int m;
      unsigned int n;

      n = 8;
      m = -64;

      if (20 < (m + n))
          printf("20 < (m + n)/n");
      else
          printf("20 >= (m + n)/n");

      printf("m+n = %d/n", m + n);
      printf("m+n = %u/n", m + n);

      system("PAUSE");
      return 0;
  }

  以上代码的输出是什么

解答:

首先也需要了解相关知识。

char,short int或者int型位段(bit-field),包括它们的有符号或无符号变型,以及枚举类型,可以使用在需要int或unsigned int的表达式中,如果int可以完整地表示源类型的所有值,那么该类型的值就转换为int,否则转换为unsigned int。

例如代码中的 m+n ,无符号数 m 相对于有符号数 n 来说能表示更多的信息,所以在两者运算的时候,m 被转换成了一个很大的无符号数,因此 m+n 的值远大于20,所以 if() 语句中的判断为真。

因此程序输出:

20 < (m + n)
m+n = -56
m+n = 4294967240

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值