Posted on 2010-03-23 14:40
S.l.e!ep.¢% 阅读(1307)
评论(2) 编辑 收藏 引用 所属分类:
C++ 、
Interview
确定一个变量是有符号数还是无符号数 收藏
读《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
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/rainbow_free/archive/2009/06/17/4275697.aspx