确定一个变量是有符号数还是无符号数

读《C专家编程》,其中一段讲面试,说是微软曾经有一道面试题:
写一段代码,确定一个变量是有符号数还是无符号数?

书上给出了两个宏:
#define ISUNSIGNED(a) (a>=0 && ~a>=0)
#define ISUNSIGNED(type) ((type)0-1 > 0)

第二个从类型来判断,没有问题。

而第一个只能用在K&R C里,在ANSI C里就不行了。
当这个宏被用在int/unsigned int时,没有任何问题。
但是当使用在char和short上就会出错。

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

ANSI C中的寻常算术转换:
当执行算术运算时,操作数的类型如果不同,就会发生转换。
数据类型一般朝着浮点精度更高、长度更长的方向转换,
整型数如果转换为signed不会丢失信息,就转换为signed,否则就转换为unsigned。
这个称为值保留(value preserving)原则。

所以,无论原先是否有符号,char和short都被转换成了signed int(整型升级)。
原先unsigned的东西变成了signed,然后再进行取反。
同时,常数0被认为是signed int类型,所以一律被判为有符号数了。

问题是一旦char或者short参与了运算,它们将被首先转换成int,
在这以后,任何操作都变成徒劳的了,int永远都是signed。
那么能否在整型升级之前让signed char/short变成负数呢?至少我现在还没想到办法。

偶使用了赖皮方法,无耻地定义了全局变量,还用了变态的逗号表达式……

于是第一个宏就变成下面这个样子了:
int r, t;
#define ISUNSIGNED(a) (t = a, r = (a>=0 && (a=~a)>=0), a = t, r)
再一想,既然用了全局变量保存a的值,还讨论干啥?于是……

int r, t;
#define ISUNSIGNED(a) (t = a, r = ((a=-1) >= 0), a = t, r)

而且这样做的前提是,假设int是最长的整型类型,并且是有符号的。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yysdsyl/archive/2007/11/14/1885829.aspx

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值